summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:19:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:01:50 +0000
commit51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch)
tree835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/third_party/blink/renderer/modules
parent6036726eb981b6c4b42047513b9d3f4ac865daac (diff)
downloadqtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/modules')
-rw-r--r--chromium/third_party/blink/renderer/modules/BUILD.gn22
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc237
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h295
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc364
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc131
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.h52
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc788
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h32
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc1772
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.h147
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc223
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_range.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_slider.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc161
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc149
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h85
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.cc109
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h67
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc255
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h39
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fetch.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc209
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc49
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc75
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/README.md24
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/badge.cc84
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/badge.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/badge.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc398
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc116
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc124
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc202
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h64
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc200
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl17
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/event_target_modules_names.json54
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc202
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc109
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_idb_key.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/README.md74
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options_accepts.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_path.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc197
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc120
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc54
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc76
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc110
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator_entry.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc585
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h203
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_get_directory_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_get_file_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc141
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc69
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.cc139
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc353
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/get_system_directory_options.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc133
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/README.md12
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_test_helper.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_client.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc124
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h75
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element_test.cc83
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc231
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h53
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc130
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc271
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/media_controls_resources.grd2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css249
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_animated_arrow.css (renamed from chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_overlay_play.css)1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc48
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_settings.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.idl41
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_idl_files.gni89
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_initializer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.cc103
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payer_errors.idl (renamed from chromium/third_party/blink/renderer/modules/payments/payer_error_fields.idl)4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_address.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_details_update.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h47
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.cc80
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_validation_errors.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators.cc109
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn24
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h89
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h32
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc218
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h59
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc128
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h57
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc94
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h69
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h65
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h57
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h77
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h73
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.cc194
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h43
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc355
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h180
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc1177
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h86
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h98
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.cc139
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h90
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.cc151
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h110
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc90
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc165
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h39
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc573
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h68
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc125
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc412
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc75
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc241
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h68
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc235
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc89
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_options.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.idl22
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc49
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/DEPS10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc118
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/registration_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc78
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.h37
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc139
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.h37
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc152
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc191
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h134
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc56
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc302
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc428
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc108
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h138
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc217
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc108
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc56
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl28
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/README.md110
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc109
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/docs/ownership.pngbin0 -> 44260 bytes
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_area.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller.cc170
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller.h110
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc176
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc159
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.h101
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.h58
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc96
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc48
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc71
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h52
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc101
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_manager.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc69
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl36
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_handle.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc76
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.cc106
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_interface.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_layer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_layer.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h8
691 files changed, 20251 insertions, 7577 deletions
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn
index 6f94a382cec..7af1d24e4be 100644
--- a/chromium/third_party/blink/renderer/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/BUILD.gn
@@ -83,6 +83,7 @@ target("jumbo_" + modules_target_type, "modules") {
deps = [
":make_modules_generated",
":module_names",
+ "//net:net",
"//third_party/blink/renderer/bindings/modules:generated",
"//third_party/blink/renderer/bindings/modules/v8:bindings_modules_impl",
"//third_party/blink/renderer/bindings/modules/v8:bindings_modules_origin_trial_features",
@@ -93,6 +94,7 @@ target("jumbo_" + modules_target_type, "modules") {
"//third_party/blink/renderer/modules/audio_output_devices",
"//third_party/blink/renderer/modules/background_fetch",
"//third_party/blink/renderer/modules/background_sync",
+ "//third_party/blink/renderer/modules/badging",
"//third_party/blink/renderer/modules/battery",
"//third_party/blink/renderer/modules/beacon",
"//third_party/blink/renderer/modules/bluetooth",
@@ -143,6 +145,7 @@ target("jumbo_" + modules_target_type, "modules") {
"//third_party/blink/renderer/modules/remoteplayback",
"//third_party/blink/renderer/modules/screen_orientation",
"//third_party/blink/renderer/modules/sensor",
+ "//third_party/blink/renderer/modules/serial",
"//third_party/blink/renderer/modules/service_worker",
"//third_party/blink/renderer/modules/shapedetection",
"//third_party/blink/renderer/modules/speech",
@@ -163,6 +166,7 @@ target("jumbo_" + modules_target_type, "modules") {
"//third_party/blink/renderer/modules/xr",
"//third_party/icu",
"//third_party/webrtc/pc:libjingle_peerconnection",
+ "//third_party/webrtc/rtc_base:rtc_base",
"//third_party/webrtc_overrides:init_webrtc",
"//third_party/zlib",
]
@@ -187,6 +191,11 @@ jumbo_source_set("modules_testing") {
"navigatorcontentutils/testing/internals_navigator_content_utils.h",
"navigatorcontentutils/testing/navigator_content_utils_client_mock.cc",
"navigatorcontentutils/testing/navigator_content_utils_client_mock.h",
+ "peerconnection/adapters/test/mock_ice_transport_adapter.h",
+ "peerconnection/adapters/test/mock_ice_transport_adapter_cross_thread_factory.h",
+ "peerconnection/adapters/test/mock_p2p_quic_packet_transport.h",
+ "peerconnection/adapters/test/mock_p2p_quic_transport.h",
+ "peerconnection/adapters/test/mock_p2p_quic_transport_factory.h",
"peerconnection/testing/internals_rtc_certificate.cc",
"peerconnection/testing/internals_rtc_certificate.h",
"peerconnection/testing/internals_rtc_peer_connection.cc",
@@ -256,6 +265,7 @@ jumbo_source_set("unit_tests") {
"document_metadata/copyless_paste_extractor_test.cc",
"eventsource/event_source_parser_test.cc",
"filesystem/dom_file_system_base_test.cc",
+ "filesystem/file_writer_test.cc",
"indexeddb/idb_key_path_test.cc",
"indexeddb/idb_request_test.cc",
"indexeddb/idb_test_helper.cc",
@@ -264,10 +274,10 @@ jumbo_source_set("unit_tests") {
"indexeddb/mock_web_idb_database.cc",
"indexeddb/mock_web_idb_database.h",
"manifest/image_resource_type_converters_test.cc",
+ "media_controls/elements/media_control_animated_arrow_container_element_test.cc",
"media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc",
"media_controls/elements/media_control_input_element_test.cc",
"media_controls/elements/media_control_loading_panel_element_test.cc",
- "media_controls/elements/media_control_overlay_play_button_element_test.cc",
"media_controls/elements/media_control_panel_element_test.cc",
"media_controls/elements/media_control_scrubbing_message_element_test.cc",
"media_controls/elements/media_control_timeline_element_test.cc",
@@ -294,8 +304,13 @@ jumbo_source_set("unit_tests") {
"payments/payment_test_helper.cc",
"payments/payment_test_helper.h",
"payments/payments_validators_test.cc",
+ "peerconnection/adapters/p2p_quic_transport_test.cc",
"peerconnection/rtc_data_channel_test.cc",
+ "peerconnection/rtc_ice_transport_test.cc",
+ "peerconnection/rtc_ice_transport_test.h",
"peerconnection/rtc_peer_connection_test.cc",
+ "peerconnection/rtc_quic_transport_test.cc",
+ "peerconnection/rtc_quic_transport_test.h",
"picture_in_picture/html_video_element_picture_in_picture_test.cc",
"presentation/mock_presentation_service.h",
"presentation/presentation_availability_state_test.cc",
@@ -308,6 +323,8 @@ jumbo_source_set("unit_tests") {
"remoteplayback/remote_playback_test.cc",
"screen_orientation/screen_orientation_controller_impl_test.cc",
"service_worker/service_worker_container_test.cc",
+ "service_worker/service_worker_installed_scripts_manager_test.cc",
+ "service_worker/thread_safe_script_container_test.cc",
"service_worker/web_embedded_worker_impl_test.cc",
"wake_lock/screen_wake_lock_test.cc",
"webaudio/audio_basic_processor_handler_test.cc",
@@ -333,7 +350,9 @@ jumbo_source_set("unit_tests") {
deps = [
":modules",
":modules_testing",
+ "//net:quic_test_tools",
"//services/device/public/cpp/test:test_support",
+ "//services/viz/public/interfaces:interfaces_blink",
"//skia",
"//testing/gmock",
"//testing/gtest",
@@ -342,6 +361,7 @@ jumbo_source_set("unit_tests") {
"//third_party/blink/renderer/modules/storage:unit_tests",
"//third_party/blink/renderer/platform",
"//third_party/blink/renderer/platform/wtf",
+ "//third_party/webrtc/rtc_base:rtc_base",
"//v8",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn b/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
index 3aadcb08e2c..c4478a9d087 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
@@ -62,6 +62,10 @@ blink_modules_sources("accessibility") {
"inspector_type_builder_helper.h",
]
+ deps = [
+ "//ui/accessibility:ax_enums_mojo_blink",
+ ]
+
# The modules/accessibility/ depends closely on core/ --
# include the core pch for faster Windows compilation times.
configs += [ "//third_party/blink/renderer/core:blink_core_pch" ]
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/DEPS b/chromium/third_party/blink/renderer/modules/accessibility/DEPS
index ec3df5f6ed4..44011c4a0c6 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/DEPS
+++ b/chromium/third_party/blink/renderer/modules/accessibility/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+mojo/public/cpp/bindings/binding.h",
+ "+ui/accessibility/ax_enums.mojom-blink.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/accessibility",
"+third_party/blink/renderer/modules/media_controls",
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
index cac291e66d8..b5cbf790b05 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
@@ -55,13 +55,13 @@ TEST_F(AccessibilityObjectModelTest, SetAccessibleNodeRole) {
ASSERT_NE(nullptr, button);
auto* axButton = cache->GetOrCreate(button);
- EXPECT_EQ(kButtonRole, axButton->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kButton, axButton->RoleValue());
button->accessibleNode()->setRole("slider");
EXPECT_EQ("slider", button->accessibleNode()->role());
axButton = cache->GetOrCreate(button);
- EXPECT_EQ(kSliderRole, axButton->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kSlider, axButton->RoleValue());
}
TEST_F(AccessibilityObjectModelTest, AOMDoesNotReflectARIA) {
@@ -81,8 +81,8 @@ TEST_F(AccessibilityObjectModelTest, AOMDoesNotReflectARIA) {
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* axTextBox = cache->GetOrCreate(textbox);
- EXPECT_EQ(kTextFieldWithComboBoxRole, axTextBox->RoleValue());
- AXNameFrom name_from;
+ EXPECT_EQ(ax::mojom::Role::kTextFieldWithComboBox, axTextBox->RoleValue());
+ ax::mojom::NameFrom name_from;
AXObject::AXObjectVector name_objects;
EXPECT_EQ("Combo", axTextBox->GetName(name_from, &name_objects));
EXPECT_EQ(axTextBox->Restriction(), kDisabled);
@@ -112,8 +112,8 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
auto* axButton = cache->GetOrCreate(button);
- EXPECT_EQ(kCheckBoxRole, axButton->RoleValue());
- AXNameFrom name_from;
+ EXPECT_EQ(ax::mojom::Role::kCheckBox, axButton->RoleValue());
+ ax::mojom::NameFrom name_from;
AXObject::AXObjectVector name_objects;
EXPECT_EQ("Check", axButton->GetName(name_from, &name_objects));
EXPECT_EQ(axButton->Restriction(), kDisabled);
@@ -125,7 +125,7 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
// Assert that the AX object was affected by AOM properties.
axButton = cache->GetOrCreate(button);
- EXPECT_EQ(kRadioButtonRole, axButton->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kRadioButton, axButton->RoleValue());
EXPECT_EQ("Radio", axButton->GetName(name_from, &name_objects));
EXPECT_EQ(axButton->Restriction(), kNone);
@@ -136,7 +136,7 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
// The AX Object should now revert to ARIA.
axButton = cache->GetOrCreate(button);
- EXPECT_EQ(kCheckBoxRole, axButton->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kCheckBox, axButton->RoleValue());
EXPECT_EQ("Check", axButton->GetName(name_from, &name_objects));
EXPECT_EQ(axButton->Restriction(), kDisabled);
}
@@ -316,16 +316,16 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
ASSERT_EQ("Widget",
sparse_attributes
.string_attributes[AXStringAttribute::kAriaRoleDescription]);
- ASSERT_EQ(kListBoxOptionRole,
+ ASSERT_EQ(ax::mojom::Role::kListBoxOption,
sparse_attributes
.object_attributes[AXObjectAttribute::kAriaActiveDescendant]
->RoleValue());
ASSERT_EQ(
- kContentInfoRole,
+ ax::mojom::Role::kContentInfo,
sparse_attributes.object_attributes[AXObjectAttribute::kAriaDetails]
->RoleValue());
ASSERT_EQ(
- kArticleRole,
+ ax::mojom::Role::kArticle,
sparse_attributes.object_attributes[AXObjectAttribute::kAriaErrorMessage]
->RoleValue());
@@ -347,14 +347,15 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
ASSERT_EQ("Object",
sparse_attributes2
.string_attributes[AXStringAttribute::kAriaRoleDescription]);
- ASSERT_EQ(kCellRole,
+ ASSERT_EQ(ax::mojom::Role::kCell,
sparse_attributes2
.object_attributes[AXObjectAttribute::kAriaActiveDescendant]
->RoleValue());
- ASSERT_EQ(kFormRole, sparse_attributes2
- .object_attributes[AXObjectAttribute::kAriaDetails]
- ->RoleValue());
- ASSERT_EQ(kBannerRole,
+ ASSERT_EQ(
+ ax::mojom::Role::kForm,
+ sparse_attributes2.object_attributes[AXObjectAttribute::kAriaDetails]
+ ->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kBanner,
sparse_attributes2
.object_attributes[AXObjectAttribute::kAriaErrorMessage]
->RoleValue());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
index a674868b4d7..7b1d31b4173 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
@@ -12,201 +12,6 @@
namespace blink {
-STATIC_ASSERT_ENUM(kWebAXRoleAbbr, kAbbrRole);
-STATIC_ASSERT_ENUM(kWebAXRoleAlertDialog, kAlertDialogRole);
-STATIC_ASSERT_ENUM(kWebAXRoleAlert, kAlertRole);
-STATIC_ASSERT_ENUM(kWebAXRoleAnchor, kAnchorRole);
-STATIC_ASSERT_ENUM(kWebAXRoleAnnotation, kAnnotationRole);
-STATIC_ASSERT_ENUM(kWebAXRoleApplication, kApplicationRole);
-STATIC_ASSERT_ENUM(kWebAXRoleArticle, kArticleRole);
-STATIC_ASSERT_ENUM(kWebAXRoleAudio, kAudioRole);
-STATIC_ASSERT_ENUM(kWebAXRoleBanner, kBannerRole);
-STATIC_ASSERT_ENUM(kWebAXRoleBlockquote, kBlockquoteRole);
-STATIC_ASSERT_ENUM(kWebAXRoleButton, kButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleCanvas, kCanvasRole);
-STATIC_ASSERT_ENUM(kWebAXRoleCaption, kCaptionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleCell, kCellRole);
-STATIC_ASSERT_ENUM(kWebAXRoleCheckBox, kCheckBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleColorWell, kColorWellRole);
-STATIC_ASSERT_ENUM(kWebAXRoleColumnHeader, kColumnHeaderRole);
-STATIC_ASSERT_ENUM(kWebAXRoleColumn, kColumnRole);
-STATIC_ASSERT_ENUM(kWebAXRoleComboBoxGrouping, kComboBoxGroupingRole);
-STATIC_ASSERT_ENUM(kWebAXRoleComboBoxMenuButton, kComboBoxMenuButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleComplementary, kComplementaryRole);
-STATIC_ASSERT_ENUM(kWebAXRoleContentDeletion, kContentDeletionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleContentInsertion, kContentInsertionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleContentInfo, kContentInfoRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDate, kDateRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDateTime, kDateTimeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDefinition, kDefinitionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDescriptionListDetail, kDescriptionListDetailRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDescriptionList, kDescriptionListRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDescriptionListTerm, kDescriptionListTermRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDetails, kDetailsRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDialog, kDialogRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDirectory, kDirectoryRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDisclosureTriangle, kDisclosureTriangleRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocAbstract, kDocAbstractRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocAcknowledgments, kDocAcknowledgmentsRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocAfterword, kDocAfterwordRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocAppendix, kDocAppendixRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocBackLink, kDocBackLinkRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocBiblioEntry, kDocBiblioEntryRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocBibliography, kDocBibliographyRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocBiblioRef, kDocBiblioRefRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocChapter, kDocChapterRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocColophon, kDocColophonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocConclusion, kDocConclusionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocCover, kDocCoverRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocCredit, kDocCreditRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocCredits, kDocCreditsRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocDedication, kDocDedicationRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocEndnote, kDocEndnoteRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocEndnotes, kDocEndnotesRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocEpigraph, kDocEpigraphRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocEpilogue, kDocEpilogueRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocErrata, kDocErrataRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocExample, kDocExampleRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocFootnote, kDocFootnoteRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocForeword, kDocForewordRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocGlossary, kDocGlossaryRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocGlossRef, kDocGlossRefRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocIndex, kDocIndexRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocIntroduction, kDocIntroductionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocNoteRef, kDocNoteRefRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocNotice, kDocNoticeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPageBreak, kDocPageBreakRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPageList, kDocPageListRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPart, kDocPartRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPreface, kDocPrefaceRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPrologue, kDocPrologueRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocPullquote, kDocPullquoteRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocQna, kDocQnaRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocSubtitle, kDocSubtitleRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocTip, kDocTipRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocToc, kDocTocRole);
-STATIC_ASSERT_ENUM(kWebAXRoleDocument, kDocumentRole);
-STATIC_ASSERT_ENUM(kWebAXRoleEmbeddedObject, kEmbeddedObjectRole);
-STATIC_ASSERT_ENUM(kWebAXRoleFeed, kFeedRole);
-STATIC_ASSERT_ENUM(kWebAXRoleFigcaption, kFigcaptionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleFigure, kFigureRole);
-STATIC_ASSERT_ENUM(kWebAXRoleFooter, kFooterRole);
-STATIC_ASSERT_ENUM(kWebAXRoleForm, kFormRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGenericContainer, kGenericContainerRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGraphicsDocument, kGraphicsDocumentRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGraphicsObject, kGraphicsObjectRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGraphicsSymbol, kGraphicsSymbolRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGrid, kGridRole);
-STATIC_ASSERT_ENUM(kWebAXRoleGroup, kGroupRole);
-STATIC_ASSERT_ENUM(kWebAXRoleHeading, kHeadingRole);
-STATIC_ASSERT_ENUM(kWebAXRoleIframe, kIframeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleIframePresentational, kIframePresentationalRole);
-STATIC_ASSERT_ENUM(kWebAXRoleIgnored, kIgnoredRole);
-STATIC_ASSERT_ENUM(kWebAXRoleImageMap, kImageMapRole);
-STATIC_ASSERT_ENUM(kWebAXRoleImage, kImageRole);
-STATIC_ASSERT_ENUM(kWebAXRoleInlineTextBox, kInlineTextBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleInputTime, kInputTimeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLabel, kLabelRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLayoutTable, kLayoutTableRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLayoutTableCell, kLayoutTableCellRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLayoutTableColumn, kLayoutTableColumnRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLayoutTableRow, kLayoutTableRowRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLegend, kLegendRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLineBreak, kLineBreakRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLink, kLinkRole);
-STATIC_ASSERT_ENUM(kWebAXRoleListBoxOption, kListBoxOptionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleListBox, kListBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleListItem, kListItemRole);
-STATIC_ASSERT_ENUM(kWebAXRoleListMarker, kListMarkerRole);
-STATIC_ASSERT_ENUM(kWebAXRoleList, kListRole);
-STATIC_ASSERT_ENUM(kWebAXRoleLog, kLogRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMain, kMainRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMark, kMarkRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMarquee, kMarqueeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMath, kMathRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuBar, kMenuBarRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuButton, kMenuButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuItem, kMenuItemRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuItemCheckBox, kMenuItemCheckBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuItemRadio, kMenuItemRadioRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuListOption, kMenuListOptionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenuListPopup, kMenuListPopupRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMenu, kMenuRole);
-STATIC_ASSERT_ENUM(kWebAXRoleMeter, kMeterRole);
-STATIC_ASSERT_ENUM(kWebAXRoleNavigation, kNavigationRole);
-STATIC_ASSERT_ENUM(kWebAXRoleNone, kNoneRole);
-STATIC_ASSERT_ENUM(kWebAXRoleNote, kNoteRole);
-STATIC_ASSERT_ENUM(kWebAXRoleParagraph, kParagraphRole);
-STATIC_ASSERT_ENUM(kWebAXRolePopUpButton, kPopUpButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRolePre, kPreRole);
-STATIC_ASSERT_ENUM(kWebAXRolePresentational, kPresentationalRole);
-STATIC_ASSERT_ENUM(kWebAXRoleProgressIndicator, kProgressIndicatorRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRadioButton, kRadioButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRadioGroup, kRadioGroupRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRegion, kRegionRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRowHeader, kRowHeaderRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRow, kRowRole);
-STATIC_ASSERT_ENUM(kWebAXRoleRuby, kRubyRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSVGRoot, kSVGRootRole);
-STATIC_ASSERT_ENUM(kWebAXRoleScrollBar, kScrollBarRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSearch, kSearchRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSearchBox, kSearchBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSlider, kSliderRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSliderThumb, kSliderThumbRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSpinButton, kSpinButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSplitter, kSplitterRole);
-STATIC_ASSERT_ENUM(kWebAXRoleStaticText, kStaticTextRole);
-STATIC_ASSERT_ENUM(kWebAXRoleStatus, kStatusRole);
-STATIC_ASSERT_ENUM(kWebAXRoleSwitch, kSwitchRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTabList, kTabListRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTabPanel, kTabPanelRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTab, kTabRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTableHeaderContainer, kTableHeaderContainerRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTable, kTableRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTerm, kTermRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTextField, kTextFieldRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTextFieldWithComboBox, kTextFieldWithComboBoxRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTime, kTimeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTimer, kTimerRole);
-STATIC_ASSERT_ENUM(kWebAXRoleToggleButton, kToggleButtonRole);
-STATIC_ASSERT_ENUM(kWebAXRoleToolbar, kToolbarRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTreeGrid, kTreeGridRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTreeItem, kTreeItemRole);
-STATIC_ASSERT_ENUM(kWebAXRoleTree, kTreeRole);
-STATIC_ASSERT_ENUM(kWebAXRoleUnknown, kUnknownRole);
-STATIC_ASSERT_ENUM(kWebAXRoleUserInterfaceTooltip, kUserInterfaceTooltipRole);
-STATIC_ASSERT_ENUM(kWebAXRoleVideo, kVideoRole);
-STATIC_ASSERT_ENUM(kWebAXRoleWebArea, kWebAreaRole);
-
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kActivate,
- AXDefaultActionVerb::kActivate);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kCheck, AXDefaultActionVerb::kCheck);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kClick, AXDefaultActionVerb::kClick);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kClickAncestor,
- AXDefaultActionVerb::kClickAncestor);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kJump, AXDefaultActionVerb::kJump);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kOpen, AXDefaultActionVerb::kOpen);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kPress, AXDefaultActionVerb::kPress);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kSelect,
- AXDefaultActionVerb::kSelect);
-STATIC_ASSERT_ENUM(WebAXDefaultActionVerb::kUncheck,
- AXDefaultActionVerb::kUncheck);
-
-STATIC_ASSERT_ENUM(kWebAXTextDirectionLR, kAccessibilityTextDirectionLTR);
-STATIC_ASSERT_ENUM(kWebAXTextDirectionRL, kAccessibilityTextDirectionRTL);
-STATIC_ASSERT_ENUM(kWebAXTextDirectionTB, kAccessibilityTextDirectionTTB);
-STATIC_ASSERT_ENUM(kWebAXTextDirectionBT, kAccessibilityTextDirectionBTT);
-
-STATIC_ASSERT_ENUM(kWebAXTextPositionNone, kAXTextPositionNone);
-STATIC_ASSERT_ENUM(kWebAXTextPositionSubscript, kAXTextPositionSubscript);
-STATIC_ASSERT_ENUM(kWebAXTextPositionSuperscript, kAXTextPositionSuperscript);
-
-STATIC_ASSERT_ENUM(kWebAXSortDirectionUndefined, kSortDirectionUndefined);
-STATIC_ASSERT_ENUM(kWebAXSortDirectionNone, kSortDirectionNone);
-STATIC_ASSERT_ENUM(kWebAXSortDirectionAscending, kSortDirectionAscending);
-STATIC_ASSERT_ENUM(kWebAXSortDirectionDescending, kSortDirectionDescending);
-STATIC_ASSERT_ENUM(kWebAXSortDirectionOther, kSortDirectionOther);
-
STATIC_ASSERT_ENUM(kWebAXExpandedUndefined, kExpandedUndefined);
STATIC_ASSERT_ENUM(kWebAXExpandedCollapsed, kExpandedCollapsed);
STATIC_ASSERT_ENUM(kWebAXExpandedExpanded, kExpandedExpanded);
@@ -218,54 +23,12 @@ STATIC_ASSERT_ENUM(kWebAXOrientationVertical,
STATIC_ASSERT_ENUM(kWebAXOrientationHorizontal,
kAccessibilityOrientationHorizontal);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateUndefined, kAriaCurrentStateUndefined);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateFalse, kAriaCurrentStateFalse);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateTrue, kAriaCurrentStateTrue);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStatePage, kAriaCurrentStatePage);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateStep, kAriaCurrentStateStep);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateLocation, kAriaCurrentStateLocation);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateDate, kAriaCurrentStateDate);
-STATIC_ASSERT_ENUM(kWebAXAriaCurrentStateTime, kAriaCurrentStateTime);
-
-STATIC_ASSERT_ENUM(kWebAXHasPopupFalse, kAXHasPopupFalse);
-STATIC_ASSERT_ENUM(kWebAXHasPopupTrue, kAXHasPopupTrue);
-STATIC_ASSERT_ENUM(kWebAXHasPopupMenu, kAXHasPopupMenu);
-STATIC_ASSERT_ENUM(kWebAXHasPopupListbox, kAXHasPopupListbox);
-STATIC_ASSERT_ENUM(kWebAXHasPopupTree, kAXHasPopupTree);
-STATIC_ASSERT_ENUM(kWebAXHasPopupGrid, kAXHasPopupGrid);
-STATIC_ASSERT_ENUM(kWebAXHasPopupDialog, kAXHasPopupDialog);
-
-STATIC_ASSERT_ENUM(kWebAXInvalidStateUndefined, kInvalidStateUndefined);
-STATIC_ASSERT_ENUM(kWebAXInvalidStateFalse, kInvalidStateFalse);
-STATIC_ASSERT_ENUM(kWebAXInvalidStateTrue, kInvalidStateTrue);
-STATIC_ASSERT_ENUM(kWebAXInvalidStateSpelling, kInvalidStateSpelling);
-STATIC_ASSERT_ENUM(kWebAXInvalidStateGrammar, kInvalidStateGrammar);
-STATIC_ASSERT_ENUM(kWebAXInvalidStateOther, kInvalidStateOther);
-
STATIC_ASSERT_ENUM(kWebAXTextStyleNone, kTextStyleNone);
STATIC_ASSERT_ENUM(kWebAXTextStyleBold, kTextStyleBold);
STATIC_ASSERT_ENUM(kWebAXTextStyleItalic, kTextStyleItalic);
STATIC_ASSERT_ENUM(kWebAXTextStyleUnderline, kTextStyleUnderline);
STATIC_ASSERT_ENUM(kWebAXTextStyleLineThrough, kTextStyleLineThrough);
-STATIC_ASSERT_ENUM(kWebAXNameFromUninitialized, kAXNameFromUninitialized);
-STATIC_ASSERT_ENUM(kWebAXNameFromAttribute, kAXNameFromAttribute);
-STATIC_ASSERT_ENUM(kWebAXNameFromAttributeExplicitlyEmpty,
- kAXNameFromAttributeExplicitlyEmpty);
-STATIC_ASSERT_ENUM(kWebAXNameFromCaption, kAXNameFromCaption);
-STATIC_ASSERT_ENUM(kWebAXNameFromContents, kAXNameFromContents);
-STATIC_ASSERT_ENUM(kWebAXNameFromPlaceholder, kAXNameFromPlaceholder);
-STATIC_ASSERT_ENUM(kWebAXNameFromRelatedElement, kAXNameFromRelatedElement);
-STATIC_ASSERT_ENUM(kWebAXNameFromValue, kAXNameFromValue);
-STATIC_ASSERT_ENUM(kWebAXNameFromTitle, kAXNameFromTitle);
-
-STATIC_ASSERT_ENUM(kWebAXDescriptionFromUninitialized,
- kAXDescriptionFromUninitialized);
-STATIC_ASSERT_ENUM(kWebAXDescriptionFromAttribute, kAXDescriptionFromAttribute);
-STATIC_ASSERT_ENUM(kWebAXDescriptionFromContents, kAXDescriptionFromContents);
-STATIC_ASSERT_ENUM(kWebAXDescriptionFromRelatedElement,
- kAXDescriptionFromRelatedElement);
-
STATIC_ASSERT_ENUM(WebAXStringAttribute::kAriaKeyShortcuts,
AXStringAttribute::kAriaKeyShortcuts);
STATIC_ASSERT_ENUM(WebAXStringAttribute::kAriaRoleDescription,
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
index 9bee8cacfae..1619d789722 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
@@ -9,210 +9,12 @@
namespace blink {
-enum AccessibilityRole {
- kUnknownRole = 0, // Not mapped in platform APIs, generally indicates a bug
- kAbbrRole, // No mapping to ARIA role.
- kAlertDialogRole,
- kAlertRole,
- kAnchorRole, // No mapping to ARIA role.
- kAnnotationRole, // No mapping to ARIA role.
- kApplicationRole,
- kArticleRole,
- kAudioRole, // No mapping to ARIA role.
- kBannerRole,
- kBlockquoteRole, // No mapping to ARIA role.
- kButtonRole,
- kCanvasRole, // No mapping to ARIA role.
- kCaptionRole, // No mapping to ARIA role.
- kCellRole,
- kCheckBoxRole,
- kColorWellRole, // No mapping to ARIA role.
- kColumnHeaderRole,
- kColumnRole, // No mapping to ARIA role.
- kComboBoxGroupingRole,
- kComboBoxMenuButtonRole,
- kComplementaryRole,
- kContentDeletionRole, // ARIA role mapping expected in ARIA v1.2.
- kContentInsertionRole, // ARIA role mapping expected in ARIA v1.2.
- kContentInfoRole,
- kDateRole, // No mapping to ARIA role.
- kDateTimeRole, // No mapping to ARIA role.
- kDefinitionRole,
- kDescriptionListDetailRole, // No mapping to ARIA role.
- kDescriptionListRole, // No mapping to ARIA role.
- kDescriptionListTermRole, // No mapping to ARIA role.
- kDetailsRole, // No mapping to ARIA role.
- kDialogRole,
- kDirectoryRole,
- kDisclosureTriangleRole, // No mapping to ARIA role.
- kDocAbstractRole,
- kDocAcknowledgmentsRole,
- kDocAfterwordRole,
- kDocAppendixRole,
- // --------------------------------------------------------------
- // DPub Roles:
- // https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
- kDocBackLinkRole,
- kDocBiblioEntryRole,
- kDocBibliographyRole,
- kDocBiblioRefRole,
- kDocChapterRole,
- kDocColophonRole,
- kDocConclusionRole,
- kDocCoverRole,
- kDocCreditRole,
- kDocCreditsRole,
- kDocDedicationRole,
- kDocEndnoteRole,
- kDocEndnotesRole,
- kDocEpigraphRole,
- kDocEpilogueRole,
- kDocErrataRole,
- kDocExampleRole,
- kDocFootnoteRole,
- kDocForewordRole,
- kDocGlossaryRole,
- kDocGlossRefRole,
- kDocIndexRole,
- kDocIntroductionRole,
- kDocNoteRefRole,
- kDocNoticeRole,
- kDocPageBreakRole,
- kDocPageListRole,
- kDocPartRole,
- kDocPrefaceRole,
- kDocPrologueRole,
- kDocPullquoteRole,
- kDocQnaRole,
- kDocSubtitleRole,
- kDocTipRole,
- kDocTocRole,
- // End DPub roles.
- // --------------------------------------------------------------
- kDocumentRole,
- kEmbeddedObjectRole, // No mapping to ARIA role.
- kFeedRole,
- kFigcaptionRole, // No mapping to ARIA role.
- kFigureRole,
- kFooterRole,
- kFormRole,
- kGenericContainerRole, // No role was defined for this container
- // --------------------------------------------------------------
- // ARIA Graphics module roles:
- // https://rawgit.com/w3c/graphics-aam/master/#mapping_role_table
- kGraphicsDocumentRole,
- kGraphicsObjectRole,
- kGraphicsSymbolRole,
- // End ARIA Graphics module roles.
- // --------------------------------------------------------------
- kGridRole,
- kGroupRole,
- kHeadingRole,
- kIframePresentationalRole, // No mapping to ARIA role.
- kIframeRole, // No mapping to ARIA role.
- kIgnoredRole, // No mapping to ARIA role.
- kImageMapRole, // No mapping to ARIA role.
- kImageRole,
- kInlineTextBoxRole, // No mapping to ARIA role.
- kInputTimeRole, // No mapping to ARIA role.
- kLabelRole,
- kLayoutTableRole,
- kLayoutTableCellRole,
- kLayoutTableColumnRole,
- kLayoutTableRowRole,
- kLegendRole, // No mapping to ARIA role.
- kLineBreakRole, // No mapping to ARIA role.
- kLinkRole,
- kListBoxOptionRole,
- kListBoxRole,
- kListItemRole,
- kListMarkerRole, // No mapping to ARIA role.
- kListRole,
- kLogRole,
- kMainRole,
- kMarkRole, // No mapping to ARIA role.
- kMarqueeRole,
- kMathRole,
- kMenuBarRole,
- kMenuButtonRole,
- kMenuItemRole,
- kMenuItemCheckBoxRole,
- kMenuItemRadioRole,
- kMenuListOptionRole,
- kMenuListPopupRole,
- kMenuRole,
- kMeterRole,
- kNavigationRole,
- kNoneRole, // ARIA role of "none"
- kNoteRole,
- kParagraphRole, // No mapping to ARIA role.
- kPopUpButtonRole,
- kPreRole, // No mapping to ARIA role.
- kPresentationalRole,
- kProgressIndicatorRole,
- kRadioButtonRole,
- kRadioGroupRole,
- kRegionRole,
- kRowHeaderRole,
- kRowRole,
- kRubyRole, // No mapping to ARIA role.
- kSVGRootRole, // No mapping to ARIA role.
- kScrollBarRole,
- kSearchRole,
- kSearchBoxRole,
- kSliderRole,
- kSliderThumbRole, // No mapping to ARIA role.
- kSpinButtonRole,
- kSplitterRole,
- kStaticTextRole, // No mapping to ARIA role.
- kStatusRole,
- kSwitchRole,
- kTabListRole,
- kTabPanelRole,
- kTabRole,
- kTableHeaderContainerRole, // No mapping to ARIA role.
- kTableRole,
- kTermRole,
- kTextFieldRole,
- kTextFieldWithComboBoxRole,
- kTimeRole, // No mapping to ARIA role.
- kTimerRole,
- kToggleButtonRole,
- kToolbarRole,
- kTreeGridRole,
- kTreeItemRole,
- kTreeRole,
- kUserInterfaceTooltipRole,
- kVideoRole, // No mapping to ARIA role.
- kWebAreaRole, // No mapping to ARIA role.
- kNumRoles
-};
-
enum AccessibilityOrientation {
kAccessibilityOrientationUndefined = 0,
kAccessibilityOrientationVertical,
kAccessibilityOrientationHorizontal,
};
-enum class AXDefaultActionVerb {
- kNone = 0,
- kActivate,
- kCheck,
- kClick,
-
- // A click will be performed on one of the object's ancestors.
- // This happens when the object itself is not clickable, but one of its
- // ancestors has click handlers attached which are able to capture the click
- // as it bubbles up.
- kClickAncestor,
-
- kJump,
- kOpen,
- kPress,
- kSelect,
- kUncheck
-};
-
// The input restriction on an object.
enum AXRestriction {
kNone = 0, // An object that is not disabled.
@@ -220,39 +22,6 @@ enum AXRestriction {
kDisabled,
};
-enum class AXSupportedAction {
- kNone = 0,
- kActivate,
- kCheck,
- kClick,
- kJump,
- kOpen,
- kPress,
- kSelect,
- kUncheck
-};
-
-enum AccessibilityTextDirection {
- kAccessibilityTextDirectionLTR,
- kAccessibilityTextDirectionRTL,
- kAccessibilityTextDirectionTTB,
- kAccessibilityTextDirectionBTT
-};
-
-enum AXTextPosition {
- kAXTextPositionNone = 0,
- kAXTextPositionSubscript,
- kAXTextPositionSuperscript
-};
-
-enum SortDirection {
- kSortDirectionUndefined = 0,
- kSortDirectionNone,
- kSortDirectionAscending,
- kSortDirectionDescending,
- kSortDirectionOther
-};
-
enum AccessibilityExpanded {
kExpandedUndefined = 0,
kExpandedCollapsed,
@@ -265,36 +34,6 @@ enum AccessibilitySelectedState {
kSelectedStateTrue,
};
-enum AriaCurrentState {
- kAriaCurrentStateUndefined = 0,
- kAriaCurrentStateFalse,
- kAriaCurrentStateTrue,
- kAriaCurrentStatePage,
- kAriaCurrentStateStep,
- kAriaCurrentStateLocation,
- kAriaCurrentStateDate,
- kAriaCurrentStateTime
-};
-
-enum AXHasPopup {
- kAXHasPopupFalse = 0,
- kAXHasPopupTrue,
- kAXHasPopupMenu,
- kAXHasPopupListbox,
- kAXHasPopupTree,
- kAXHasPopupGrid,
- kAXHasPopupDialog
-};
-
-enum InvalidState {
- kInvalidStateUndefined = 0,
- kInvalidStateFalse,
- kInvalidStateTrue,
- kInvalidStateSpelling,
- kInvalidStateGrammar,
- kInvalidStateOther
-};
-
enum TextStyle {
kTextStyleNone = 0,
kTextStyleBold = 1 << 0,
@@ -323,44 +62,12 @@ enum class AXObjectVectorAttribute {
kAriaFlowTo,
};
-// The source of the accessible name of an element. This is needed
-// because on some platforms this determines how the accessible name
-// is exposed.
-enum AXNameFrom {
- kAXNameFromUninitialized = -1,
- kAXNameFromAttribute = 0,
- kAXNameFromAttributeExplicitlyEmpty,
- kAXNameFromCaption,
- kAXNameFromContents,
- kAXNameFromPlaceholder,
- kAXNameFromRelatedElement,
- kAXNameFromValue,
- kAXNameFromTitle,
-};
-
-// The source of the accessible description of an element. This is needed
-// because on some platforms this determines how the accessible description
-// is exposed.
-enum AXDescriptionFrom {
- kAXDescriptionFromUninitialized = -1,
- kAXDescriptionFromAttribute = 0,
- kAXDescriptionFromContents,
- kAXDescriptionFromRelatedElement,
-};
-
enum AXObjectInclusion {
kIncludeObject,
kIgnoreObject,
kDefaultBehavior,
};
-enum AccessibilityCheckedState {
- kCheckedStateUndefined = 0,
- kCheckedStateFalse,
- kCheckedStateTrue,
- kCheckedStateMixed
-};
-
enum AccessibilityOptionalBool {
kOptionalBoolUndefined = 0,
kOptionalBoolTrue,
@@ -395,7 +102,7 @@ enum AXIgnoredReason {
kAXLabelFor,
kAXNotRendered,
kAXNotVisible,
- kAXPresentationalRole,
+ kAXPresentational,
kAXProbablyPresentational,
kAXStaticTextUsedAsNameFor,
kAXUninteresting
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
index a3025d4e553..3a1dde79006 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc
@@ -68,13 +68,13 @@ AXObject* AXImageMapLink::ComputeParent() const {
return AXObjectCache().GetOrCreate(MapElement()->GetLayoutObject());
}
-AccessibilityRole AXImageMapLink::RoleValue() const {
+ax::mojom::Role AXImageMapLink::RoleValue() const {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (!aria_role.IsEmpty())
return AXObject::AriaRoleToWebCoreRole(aria_role);
- return kLinkRole;
+ return ax::mojom::Role::kLink;
}
bool AXImageMapLink::ComputeAccessibilityIsIgnored(
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
index 75084f36967..0f6fe6d99b6 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h
@@ -51,7 +51,7 @@ class AXImageMapLink final : public AXNodeObject {
HTMLMapElement* MapElement() const;
- AccessibilityRole RoleValue() const override;
+ ax::mojom::Role RoleValue() const override;
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
Element* AnchorElement() const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
index 2a3837fb577..cc2f3aaa45f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
@@ -128,12 +128,12 @@ void AXInlineTextBox::GetWordBoundaries(Vector<AXRange>& words) const {
}
}
-String AXInlineTextBox::GetName(AXNameFrom& name_from,
+String AXInlineTextBox::GetName(ax::mojom::NameFrom& name_from,
AXObject::AXObjectVector* name_objects) const {
if (!inline_text_box_)
return String();
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
return inline_text_box_->GetText();
}
@@ -149,19 +149,19 @@ AXObject* AXInlineTextBox::ComputeParent() const {
// In addition to LTR and RTL direction, edit fields also support
// top to bottom and bottom to top via the CSS writing-mode property.
-AccessibilityTextDirection AXInlineTextBox::GetTextDirection() const {
+ax::mojom::TextDirection AXInlineTextBox::GetTextDirection() const {
if (!inline_text_box_)
return AXObject::GetTextDirection();
switch (inline_text_box_->GetDirection()) {
case AbstractInlineTextBox::kLeftToRight:
- return kAccessibilityTextDirectionLTR;
+ return ax::mojom::TextDirection::kLtr;
case AbstractInlineTextBox::kRightToLeft:
- return kAccessibilityTextDirectionRTL;
+ return ax::mojom::TextDirection::kRtl;
case AbstractInlineTextBox::kTopToBottom:
- return kAccessibilityTextDirectionTTB;
+ return ax::mojom::TextDirection::kTtb;
case AbstractInlineTextBox::kBottomToTop:
- return kAccessibilityTextDirectionBTT;
+ return ax::mojom::TextDirection::kBtt;
}
return AXObject::GetTextDirection();
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
index 7e39dc6ffb9..8d0dfdb5c68 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
@@ -53,8 +53,10 @@ class AXInlineTextBox final : public AXObject {
bool IsAXInlineTextBox() const override { return true; }
public:
- AccessibilityRole RoleValue() const override { return kInlineTextBoxRole; }
- String GetName(AXNameFrom&,
+ ax::mojom::Role RoleValue() const override {
+ return ax::mojom::Role::kInlineTextBox;
+ }
+ String GetName(ax::mojom::NameFrom&,
AXObject::AXObjectVector* name_objects) const override;
void TextCharacterOffsets(Vector<int>&) const override;
void GetWordBoundaries(Vector<AXRange>&) const override;
@@ -63,7 +65,7 @@ class AXInlineTextBox final : public AXObject {
SkMatrix44& out_container_transform,
bool* clips_children = nullptr) const override;
AXObject* ComputeParent() const override;
- AccessibilityTextDirection GetTextDirection() const override;
+ ax::mojom::TextDirection GetTextDirection() const override;
Node* GetNode() const override;
AXObject* NextOnLine() const override;
AXObject* PreviousOnLine() const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index 83d3bc2792d..c61588ea1d9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -284,70 +284,74 @@ static bool IsImageOrAltText(LayoutBoxModelObject* box, Node* node) {
return false;
}
-AccessibilityRole AXLayoutObject::NativeAccessibilityRoleIgnoringAria() const {
+ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const {
Node* node = layout_object_->GetNode();
LayoutBoxModelObject* css_box = GetLayoutBoxModelObject();
if ((css_box && css_box->IsListItem()) || IsHTMLLIElement(node))
- return kListItemRole;
+ return ax::mojom::Role::kListItem;
if (layout_object_->IsListMarkerIncludingNG())
- return kListMarkerRole;
+ return ax::mojom::Role::kListMarker;
if (layout_object_->IsBR())
- return kLineBreakRole;
+ return ax::mojom::Role::kLineBreak;
if (layout_object_->IsText())
- return kStaticTextRole;
- if (layout_object_->IsTable() && node)
- return IsDataTable() ? kTableRole : kLayoutTableRole;
+ return ax::mojom::Role::kStaticText;
+ if (layout_object_->IsTable() && node) {
+ return IsDataTable() ? ax::mojom::Role::kTable
+ : ax::mojom::Role::kLayoutTable;
+ }
if (layout_object_->IsTableRow() && node)
return DetermineTableRowRole();
if (layout_object_->IsTableCell() && node)
return DetermineTableCellRole();
if (css_box && IsImageOrAltText(css_box, node)) {
if (node && node->IsLink())
- return kImageMapRole;
+ return ax::mojom::Role::kImageMap;
if (IsHTMLInputElement(node))
return ButtonRoleType();
if (IsSVGImage())
- return kSVGRootRole;
+ return ax::mojom::Role::kSvgRoot;
- return kImageRole;
+ return ax::mojom::Role::kImage;
}
if (IsHTMLCanvasElement(node))
- return kCanvasRole;
+ return ax::mojom::Role::kCanvas;
if (css_box && css_box->IsLayoutView())
- return kWebAreaRole;
+ return ax::mojom::Role::kRootWebArea;
if (layout_object_->IsSVGImage())
- return kImageRole;
+ return ax::mojom::Role::kImage;
if (layout_object_->IsSVGRoot())
- return kSVGRootRole;
+ return ax::mojom::Role::kSvgRoot;
// Table sections should be ignored.
if (layout_object_->IsTableSection())
- return kIgnoredRole;
+ return ax::mojom::Role::kIgnored;
if (layout_object_->IsHR())
- return kSplitterRole;
+ return ax::mojom::Role::kSplitter;
- return AXNodeObject::NativeAccessibilityRoleIgnoringAria();
+ return AXNodeObject::NativeRoleIgnoringAria();
}
-AccessibilityRole AXLayoutObject::DetermineAccessibilityRole() {
+ax::mojom::Role AXLayoutObject::DetermineAccessibilityRole() {
if (!layout_object_)
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
- native_role_ = NativeAccessibilityRoleIgnoringAria();
+ native_role_ = NativeRoleIgnoringAria();
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
// Anything that needs to still be exposed but doesn't have a more specific
// role should be considered a generic container. Examples are
// layout blocks with no node, in-page link targets, and plain elements
// such as a <span> with ARIA markup.
- return native_role_ == kUnknownRole ? kGenericContainerRole : native_role_;
+ return native_role_ == ax::mojom::Role::kUnknown
+ ? ax::mojom::Role::kGenericContainer
+ : native_role_;
}
Node* AXLayoutObject::GetNodeOrContainingBlockNode() const {
@@ -396,13 +400,28 @@ bool AXLayoutObject::IsEditable() const {
if (IsDetached())
return false;
- if (GetLayoutObject()->IsTextControl())
- return true;
-
const Node* node = GetNodeOrContainingBlockNode();
if (!node)
return false;
+ // TODO(accessibility) pursue standards track so that aria-goog-editable
+ // becomes aria-editable. At that time, create ariaEditableAttr in
+ // html_element.cc. The current version of the editable attribute does not
+ // inherit, in order to match the automatic Gecko implementation, but
+ // hopefully the standardized version will, in which case a more performant
+ // implementation will be required, e.g. cache it or only expose on ancestor,
+ // having browser-side propagate it.
+ const Element* elem = node->IsElementNode()
+ ? ToElement(node)
+ : FlatTreeTraversal::ParentElement(*node);
+ if (elem && elem->hasAttribute("aria-goog-editable")) {
+ auto editable = elem->getAttribute("aria-goog-editable");
+ return !EqualIgnoringASCIICase("false", editable);
+ }
+
+ if (GetLayoutObject()->IsTextControl())
+ return true;
+
if (HasEditableStyle(*node))
return true;
@@ -430,6 +449,21 @@ bool AXLayoutObject::IsRichlyEditable() const {
if (!node)
return false;
+ // TODO(accessibility) pursue standards track so that aria-goog-editable
+ // becomes aria-editable. At that time, create ariaEditableAttr in
+ // html_element.cc. The current version of the editable attribute does not
+ // inherit, in order to match the automatic Gecko implementation, but
+ // hopefully the standardized version will, in which case a more performant
+ // implementation will be required, e.g. cache it or only expose on ancestor,
+ // having browser-side propagate it.
+ const Element* elem = node->IsElementNode()
+ ? ToElement(node)
+ : FlatTreeTraversal::ParentElement(*node);
+ if (elem && elem->hasAttribute("aria-goog-editable")) {
+ auto editable = elem->getAttribute("aria-goog-editable");
+ return !EqualIgnoringASCIICase("false", editable);
+ }
+
if (HasRichlyEditableStyle(*node))
return true;
@@ -463,7 +497,7 @@ bool AXLayoutObject::IsLoaded() const {
bool AXLayoutObject::IsOffScreen() const {
DCHECK(layout_object_);
IntRect content_rect =
- PixelSnappedIntRect(layout_object_->AbsoluteVisualRect());
+ PixelSnappedIntRect(layout_object_->VisualRectInDocument());
LocalFrameView* view = layout_object_->GetFrame()->View();
IntRect view_rect(IntPoint(), view->Size());
view_rect.Intersect(content_rect);
@@ -496,7 +530,7 @@ bool AXLayoutObject::IsFocused() const {
// A web area is represented by the Document node in the DOM tree, which isn't
// focusable. Check instead if the frame's selection controller is focused
if (focused_object == this ||
- (RoleValue() == kWebAreaRole &&
+ (RoleValue() == ax::mojom::Role::kRootWebArea &&
GetDocument()->GetFrame()->Selection().FrameIsFocusedAndActive()))
return true;
@@ -595,6 +629,30 @@ static bool HasLineBox(const LayoutBlockFlow& block_flow) {
return false;
}
+// Is this the anonymous placeholder for a text control?
+bool AXLayoutObject::IsPlaceholder() const {
+ AXObject* parent_object = ParentObject();
+ if (!parent_object)
+ return false;
+
+ LayoutObject* parent_layout_object = parent_object->GetLayoutObject();
+ if (!parent_layout_object || !parent_layout_object->IsTextControl())
+ return false;
+
+ LayoutTextControl* layout_text_control =
+ ToLayoutTextControl(parent_layout_object);
+ DCHECK(layout_text_control);
+
+ TextControlElement* text_control_element =
+ layout_text_control->GetTextControlElement();
+ if (!text_control_element)
+ return false;
+
+ HTMLElement* placeholder_element = text_control_element->PlaceholderElement();
+
+ return GetElement() == static_cast<Element*>(placeholder_element);
+}
+
bool AXLayoutObject::ComputeAccessibilityIsIgnored(
IgnoredReasons* ignored_reasons) const {
#if DCHECK_IS_ON()
@@ -625,7 +683,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
return true;
}
- if (RoleValue() == kIgnoredRole) {
+ if (RoleValue() == ax::mojom::Role::kIgnored) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
@@ -635,7 +693,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (ignored_reasons) {
const AXObject* inherits_from = InheritsPresentationalRoleFrom();
if (inherits_from == this)
- ignored_reasons->push_back(IgnoredReason(kAXPresentationalRole));
+ ignored_reasons->push_back(IgnoredReason(kAXPresentational));
else
ignored_reasons->push_back(
IgnoredReason(kAXInheritsPresentation, inherits_from));
@@ -653,8 +711,18 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
// Make sure renderers with layers stay in the tree.
if (GetLayoutObject() && GetLayoutObject()->HasLayer() && GetNode() &&
- GetNode()->hasChildren())
+ GetNode()->hasChildren()) {
+ if (IsPlaceholder()) {
+ // Placeholder is already exposed via AX attributes, do not expose as
+ // child of text input. Therefore, if there is a child of a text input,
+ // it will contain the value.
+ if (ignored_reasons)
+ ignored_reasons->push_back(IgnoredReason(kAXPresentational));
+ return true;
+ }
+
return false;
+ }
// Find out if this element is inside of a label element. If so, it may be
// ignored because it's the label for a checkbox or radio button.
@@ -688,8 +756,8 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
// A click handler might be placed on an otherwise ignored non-empty block
// element, e.g. a div. We shouldn't ignore such elements because if an AT
- // sees the |AXDefaultActionVerb::kClickAncestor|, it will look for the
- // clickable ancestor and it expects to find one.
+ // sees the |ax::mojom::DefaultActionVerb::kClickAncestor|, it will look for
+ // the clickable ancestor and it expects to find one.
if (IsClickable())
return false;
@@ -718,7 +786,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (IsControl())
return false;
- if (AriaRoleAttribute() != kUnknownRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
return false;
// don't ignore labels, because they serve as TitleUIElements
@@ -733,58 +801,58 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (HasContentEditableAttributeSet())
return false;
- if (RoleValue() == kAbbrRole)
+ if (RoleValue() == ax::mojom::Role::kAbbr)
return false;
// List items play an important role in defining the structure of lists. They
// should not be ignored.
- if (RoleValue() == kListItemRole)
+ if (RoleValue() == ax::mojom::Role::kListItem)
return false;
- if (RoleValue() == kBlockquoteRole)
+ if (RoleValue() == ax::mojom::Role::kBlockquote)
return false;
- if (RoleValue() == kDialogRole)
+ if (RoleValue() == ax::mojom::Role::kDialog)
return false;
- if (RoleValue() == kFigcaptionRole)
+ if (RoleValue() == ax::mojom::Role::kFigcaption)
return false;
- if (RoleValue() == kFigureRole)
+ if (RoleValue() == ax::mojom::Role::kFigure)
return false;
- if (RoleValue() == kContentDeletionRole)
+ if (RoleValue() == ax::mojom::Role::kContentDeletion)
return false;
- if (RoleValue() == kContentInsertionRole)
+ if (RoleValue() == ax::mojom::Role::kContentInsertion)
return false;
- if (RoleValue() == kDetailsRole)
+ if (RoleValue() == ax::mojom::Role::kDetails)
return false;
- if (RoleValue() == kMarkRole)
+ if (RoleValue() == ax::mojom::Role::kMark)
return false;
- if (RoleValue() == kMathRole)
+ if (RoleValue() == ax::mojom::Role::kMath)
return false;
- if (RoleValue() == kMeterRole)
+ if (RoleValue() == ax::mojom::Role::kMeter)
return false;
- if (RoleValue() == kRubyRole)
+ if (RoleValue() == ax::mojom::Role::kRuby)
return false;
- if (RoleValue() == kSplitterRole)
+ if (RoleValue() == ax::mojom::Role::kSplitter)
return false;
- if (RoleValue() == kTimeRole)
+ if (RoleValue() == ax::mojom::Role::kTime)
return false;
- if (RoleValue() == kProgressIndicatorRole)
+ if (RoleValue() == ax::mojom::Role::kProgressIndicator)
return false;
// if this element has aria attributes on it, it should not be ignored.
- if (SupportsARIAAttributes())
+ if (HasGlobalARIAAttribute())
return false;
if (IsImage())
@@ -837,6 +905,14 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (layout_object_->IsPositioned())
return false;
+ // Inner editor element of editable area with empty text provides bounds
+ // used to compute the character extent for index 0. This is the same as
+ // what the caret's bounds would be if the editable area is focused.
+ if (ParentObject() && ParentObject()->GetLayoutObject() &&
+ ParentObject()->GetLayoutObject()->IsTextControl()) {
+ return false;
+ }
+
// Ignore layout objects that are block flows with inline children. These
// are usually dummy layout objects that pad out the tree, but there are
// some exceptions below.
@@ -868,9 +944,10 @@ bool AXLayoutObject::HasAriaCellRole(Element* elem) const {
if (aria_role_str.IsEmpty())
return false;
- AccessibilityRole aria_role = AriaRoleToWebCoreRole(aria_role_str);
- return aria_role == kCellRole || aria_role == kColumnHeaderRole ||
- aria_role == kRowHeaderRole;
+ ax::mojom::Role aria_role = AriaRoleToWebCoreRole(aria_role_str);
+ return aria_role == ax::mojom::Role::kCell ||
+ aria_role == ax::mojom::Role::kColumnHeader ||
+ aria_role == ax::mojom::Role::kRowHeader;
}
// Return true if whitespace is not necessary to keep adjacent_node separate
@@ -1118,7 +1195,8 @@ String AXLayoutObject::ImageDataUrl(const IntSize& max_size) const {
SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType);
size_t row_bytes = info.minRowBytes();
- Vector<char> pixel_storage(info.computeByteSize(row_bytes));
+ Vector<char> pixel_storage(
+ SafeCast<wtf_size_t>(info.computeByteSize(row_bytes)));
SkPixmap pixmap(info, pixel_storage.data(), row_bytes);
if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0))
return String();
@@ -1171,7 +1249,7 @@ String AXLayoutObject::GetText() const {
return AXNodeObject::GetText();
}
-AccessibilityTextDirection AXLayoutObject::GetTextDirection() const {
+ax::mojom::TextDirection AXLayoutObject::GetTextDirection() const {
if (!GetLayoutObject())
return AXNodeObject::GetTextDirection();
@@ -1182,23 +1260,23 @@ AccessibilityTextDirection AXLayoutObject::GetTextDirection() const {
if (style->IsHorizontalWritingMode()) {
switch (style->Direction()) {
case TextDirection::kLtr:
- return kAccessibilityTextDirectionLTR;
+ return ax::mojom::TextDirection::kLtr;
case TextDirection::kRtl:
- return kAccessibilityTextDirectionRTL;
+ return ax::mojom::TextDirection::kRtl;
}
} else {
switch (style->Direction()) {
case TextDirection::kLtr:
- return kAccessibilityTextDirectionTTB;
+ return ax::mojom::TextDirection::kTtb;
case TextDirection::kRtl:
- return kAccessibilityTextDirectionBTT;
+ return ax::mojom::TextDirection::kBtt;
}
}
return AXNodeObject::GetTextDirection();
}
-AXTextPosition AXLayoutObject::GetTextPosition() const {
+ax::mojom::TextPosition AXLayoutObject::GetTextPosition() const {
if (!GetLayoutObject())
return AXNodeObject::GetTextPosition();
@@ -1217,9 +1295,9 @@ AXTextPosition AXLayoutObject::GetTextPosition() const {
case EVerticalAlign::kLength:
return AXNodeObject::GetTextPosition();
case EVerticalAlign::kSub:
- return kAXTextPositionSubscript;
+ return ax::mojom::TextPosition::kSubscript;
case EVerticalAlign::kSuper:
- return kAXTextPositionSuperscript;
+ return ax::mojom::TextPosition::kSuperscript;
}
}
@@ -1505,7 +1583,7 @@ String AXLayoutObject::StringValue() const {
String AXLayoutObject::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
if (layout_object_) {
@@ -1546,7 +1624,7 @@ String AXLayoutObject::TextAlternative(bool recursive,
}
if (found_text_alternative) {
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(false));
name_sources->back().type = name_from;
@@ -1575,24 +1653,24 @@ void AXLayoutObject::AriaDescribedbyElements(
describedby);
}
-AXHasPopup AXLayoutObject::HasPopup() const {
+ax::mojom::HasPopup AXLayoutObject::HasPopup() const {
const AtomicString& has_popup =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kHasPopUp);
if (!has_popup.IsNull()) {
if (EqualIgnoringASCIICase(has_popup, "false"))
- return kAXHasPopupFalse;
+ return ax::mojom::HasPopup::kFalse;
if (EqualIgnoringASCIICase(has_popup, "listbox"))
- return kAXHasPopupListbox;
+ return ax::mojom::HasPopup::kListbox;
if (EqualIgnoringASCIICase(has_popup, "tree"))
- return kAXHasPopupTree;
+ return ax::mojom::HasPopup::kTree;
if (EqualIgnoringASCIICase(has_popup, "grid"))
- return kAXHasPopupGrid;
+ return ax::mojom::HasPopup::kGrid;
if (EqualIgnoringASCIICase(has_popup, "dialog"))
- return kAXHasPopupDialog;
+ return ax::mojom::HasPopup::kDialog;
// To provide backward compatibility with ARIA 1.0 content,
// user agents MUST treat an aria-haspopup value of true
@@ -1600,13 +1678,13 @@ AXHasPopup AXLayoutObject::HasPopup() const {
// And unknown value also return menu too.
if (EqualIgnoringASCIICase(has_popup, "true") ||
EqualIgnoringASCIICase(has_popup, "menu") || !has_popup.IsEmpty())
- return kAXHasPopupMenu;
+ return ax::mojom::HasPopup::kMenu;
}
// ARIA 1.1 default value of haspopup for combobox is "listbox".
- if (RoleValue() == kComboBoxMenuButtonRole ||
- RoleValue() == kTextFieldWithComboBoxRole)
- return kAXHasPopupListbox;
+ if (RoleValue() == ax::mojom::Role::kComboBoxMenuButton ||
+ RoleValue() == ax::mojom::Role::kTextFieldWithComboBox)
+ return ax::mojom::HasPopup::kListbox;
return AXObject::HasPopup();
}
@@ -1654,13 +1732,13 @@ const AtomicString& AXLayoutObject::LiveRegionStatus() const {
// These roles have implicit live region status.
if (live_region_status.IsEmpty()) {
switch (RoleValue()) {
- case kAlertRole:
+ case ax::mojom::Role::kAlert:
return live_region_status_assertive;
- case kLogRole:
- case kStatusRole:
+ case ax::mojom::Role::kLog:
+ case ax::mojom::Role::kStatus:
return live_region_status_polite;
- case kTimerRole:
- case kMarqueeRole:
+ case ax::mojom::Role::kTimer:
+ case ax::mojom::Role::kMarquee:
return live_region_status_off;
default:
break;
@@ -1760,12 +1838,12 @@ AXObject* AXLayoutObject::ComputeParent() const {
if (!layout_object_)
return nullptr;
- if (AriaRoleAttribute() == kMenuBarRole)
+ if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar)
return AXObjectCache().GetOrCreate(layout_object_->Parent());
// menuButton and its corresponding menu are DOM siblings, but Accessibility
// needs them to be parent/child.
- if (AriaRoleAttribute() == kMenuRole) {
+ if (AriaRoleAttribute() == ax::mojom::Role::kMenu) {
AXObject* parent = MenuButtonForMenu();
if (parent)
return parent;
@@ -1788,12 +1866,12 @@ AXObject* AXLayoutObject::ComputeParentIfExists() const {
if (!layout_object_)
return nullptr;
- if (AriaRoleAttribute() == kMenuBarRole)
+ if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar)
return AXObjectCache().Get(layout_object_->Parent());
// menuButton and its corresponding menu are DOM siblings, but Accessibility
// needs them to be parent/child.
- if (AriaRoleAttribute() == kMenuRole) {
+ if (AriaRoleAttribute() == ax::mojom::Role::kMenu) {
AXObject* parent = MenuButtonForMenuIfExists();
if (parent)
return parent;
@@ -2414,7 +2492,7 @@ void AXLayoutObject::HandleActiveDescendantChanged() {
return;
AXObject* focused_object = AXObjectCache().FocusedObject();
- if (focused_object == this && SupportsARIAActiveDescendant()) {
+ if (focused_object == this) {
AXObject* active_descendant = ActiveDescendant();
if (active_descendant && active_descendant->IsSelectedFromFocus()) {
// In single selection containers, selection follows focus, so a selection
@@ -2423,8 +2501,10 @@ void AXLayoutObject::HandleActiveDescendantChanged() {
// the user navigates through the items.
AXObjectCache().HandleAriaSelectedChanged(active_descendant->GetNode());
}
- AXObjectCache().PostNotification(
- GetLayoutObject(), AXObjectCacheImpl::kAXActiveDescendantChanged);
+
+ // Mark this node dirty. AXEventGenerator will automatically infer
+ // that the active descendant changed.
+ AXObjectCache().MarkAXObjectDirty(this, false);
}
}
@@ -2435,11 +2515,11 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
bool found_parent = false;
switch (container_parent->RoleValue()) {
- case kLayoutTableRole:
- case kTreeRole:
- case kTreeGridRole:
- case kGridRole:
- case kTableRole:
+ case ax::mojom::Role::kLayoutTable:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTable:
found_parent = true;
break;
default:
@@ -2453,25 +2533,25 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
}
// Post that the row count changed.
- if (container_parent)
+ if (container_parent) {
AXObjectCache().PostNotification(container_parent,
- AXObjectCacheImpl::kAXRowCountChanged);
+ ax::mojom::Event::kRowCountChanged);
+ }
// Post that the specific row either collapsed or expanded.
AccessibilityExpanded expanded = IsExpanded();
if (!expanded)
return;
- if (RoleValue() == kRowRole || RoleValue() == kTreeItemRole) {
- AXObjectCacheImpl::AXNotification notification =
- AXObjectCacheImpl::kAXRowExpanded;
+ if (RoleValue() == ax::mojom::Role::kRow ||
+ RoleValue() == ax::mojom::Role::kTreeItem) {
+ ax::mojom::Event notification = ax::mojom::Event::kRowExpanded;
if (expanded == kExpandedCollapsed)
- notification = AXObjectCacheImpl::kAXRowCollapsed;
+ notification = ax::mojom::Event::kRowCollapsed;
AXObjectCache().PostNotification(this, notification);
} else {
- AXObjectCache().PostNotification(this,
- AXObjectCacheImpl::kAXExpandedChanged);
+ AXObjectCache().PostNotification(this, ax::mojom::Event::kExpandedChanged);
}
}
@@ -2481,7 +2561,7 @@ void AXLayoutObject::HandleAutofillStateChanged(bool is_available) {
// Reusing the value change event in order to invalidate, even though the
// value did not necessarily change.
// TODO(dmazzoni) change to using a MarkDirty() API.
- AXObjectCache().PostNotification(this, AXObjectCacheImpl::kAXValueChanged);
+ AXObjectCache().PostNotification(this, ax::mojom::Event::kValueChanged);
}
}
@@ -2491,7 +2571,7 @@ void AXLayoutObject::TextChanged() {
Settings* settings = GetDocument()->GetSettings();
if (settings && settings->GetInlineTextBoxAccessibilityEnabled() &&
- RoleValue() == kStaticTextRole)
+ RoleValue() == ax::mojom::Role::kStaticText)
ChildrenChanged();
// Do this last - AXNodeObject::textChanged posts live region announcements,
@@ -2632,7 +2712,8 @@ void AXLayoutObject::LineBreaks(Vector<int>& line_breaks) const {
}
// The following is a heuristic used to determine if a
-// <table> should be with kTableRole or kLayoutTableRole.
+// <table> should be with ax::mojom::Role::kTable or
+// ax::mojom::Role::kLayoutTable.
bool AXLayoutObject::IsDataTable() const {
if (!layout_object_ || !GetNode())
return false;
@@ -2840,7 +2921,7 @@ bool AXLayoutObject::IsDataTable() const {
}
unsigned AXLayoutObject::ColumnCount() const {
- if (AriaRoleAttribute() != kUnknownRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
return AXNodeObject::ColumnCount();
LayoutObject* layout_object = GetLayoutObject();
@@ -2857,7 +2938,7 @@ unsigned AXLayoutObject::ColumnCount() const {
}
unsigned AXLayoutObject::RowCount() const {
- if (AriaRoleAttribute() != kUnknownRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
return AXNodeObject::RowCount();
LayoutObject* layout_object = GetLayoutObject();
@@ -2954,99 +3035,100 @@ unsigned AXLayoutObject::RowSpan() const {
return cell->ResolvedRowSpan();
}
-SortDirection AXLayoutObject::GetSortDirection() const {
- if (RoleValue() != kRowHeaderRole && RoleValue() != kColumnHeaderRole)
- return kSortDirectionUndefined;
+ax::mojom::SortDirection AXLayoutObject::GetSortDirection() const {
+ if (RoleValue() != ax::mojom::Role::kRowHeader &&
+ RoleValue() != ax::mojom::Role::kColumnHeader)
+ return ax::mojom::SortDirection::kNone;
const AtomicString& aria_sort =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kSort);
if (aria_sort.IsEmpty())
- return kSortDirectionUndefined;
+ return ax::mojom::SortDirection::kNone;
if (EqualIgnoringASCIICase(aria_sort, "none"))
- return kSortDirectionNone;
+ return ax::mojom::SortDirection::kNone;
if (EqualIgnoringASCIICase(aria_sort, "ascending"))
- return kSortDirectionAscending;
+ return ax::mojom::SortDirection::kAscending;
if (EqualIgnoringASCIICase(aria_sort, "descending"))
- return kSortDirectionDescending;
+ return ax::mojom::SortDirection::kDescending;
// Technically, illegal values should be exposed as is, but this does
// not seem to be worth the implementation effort at this time.
- return kSortDirectionOther;
+ return ax::mojom::SortDirection::kOther;
}
-static AccessibilityRole DecideRoleFromSibling(LayoutTableCell* sibling_cell) {
+static ax::mojom::Role DecideRoleFromSibling(LayoutTableCell* sibling_cell) {
if (!sibling_cell)
- return kCellRole;
+ return ax::mojom::Role::kCell;
if (Node* sibling_node = sibling_cell->GetNode()) {
if (sibling_node->HasTagName(thTag))
- return kColumnHeaderRole;
+ return ax::mojom::Role::kColumnHeader;
if (sibling_node->HasTagName(tdTag))
- return kRowHeaderRole;
+ return ax::mojom::Role::kRowHeader;
}
- return kCellRole;
+ return ax::mojom::Role::kCell;
}
-AccessibilityRole AXLayoutObject::DetermineTableRowRole() const {
+ax::mojom::Role AXLayoutObject::DetermineTableRowRole() const {
AXObject* parent = ParentObjectUnignored();
if (!parent)
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
- if (parent->RoleValue() == kLayoutTableRole)
- return kLayoutTableRowRole;
+ if (parent->RoleValue() == ax::mojom::Role::kLayoutTable)
+ return ax::mojom::Role::kLayoutTableRow;
if (parent->IsTableLikeRole())
- return kRowRole;
+ return ax::mojom::Role::kRow;
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
}
-AccessibilityRole AXLayoutObject::DetermineTableCellRole() const {
+ax::mojom::Role AXLayoutObject::DetermineTableCellRole() const {
DCHECK(layout_object_);
AXObject* parent = ParentObjectUnignored();
if (!parent || !parent->IsTableRowLikeRole())
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
AXObject* grandparent = parent->ParentObjectUnignored();
if (!grandparent || !grandparent->IsTableLikeRole())
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
- if (parent->RoleValue() == kLayoutTableRowRole)
- return kLayoutTableCellRole;
+ if (parent->RoleValue() == ax::mojom::Role::kLayoutTableRow)
+ return ax::mojom::Role::kLayoutTableCell;
if (!parent->IsTableRowLikeRole())
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
if (!GetNode() || !GetNode()->HasTagName(thTag))
- return kCellRole;
+ return ax::mojom::Role::kCell;
const AtomicString& scope = GetAttribute(scopeAttr);
if (EqualIgnoringASCIICase(scope, "row") ||
EqualIgnoringASCIICase(scope, "rowgroup"))
- return kRowHeaderRole;
+ return ax::mojom::Role::kRowHeader;
if (EqualIgnoringASCIICase(scope, "col") ||
EqualIgnoringASCIICase(scope, "colgroup"))
- return kColumnHeaderRole;
+ return ax::mojom::Role::kColumnHeader;
// Check the previous cell and the next cell on the same row.
LayoutTableCell* layout_cell = ToLayoutTableCell(layout_object_);
- AccessibilityRole header_role = kCellRole;
+ ax::mojom::Role header_role = ax::mojom::Role::kCell;
// if header is preceded by header cells on the same row, then it is a
// column header. If it is preceded by other cells then it's a row header.
if ((header_role = DecideRoleFromSibling(layout_cell->PreviousCell())) !=
- kCellRole)
+ ax::mojom::Role::kCell)
return header_role;
// if header is followed by header cells on the same row, then it is a
// column header. If it is followed by other cells then it's a row header.
if ((header_role = DecideRoleFromSibling(layout_cell->NextCell())) !=
- kCellRole)
+ ax::mojom::Role::kCell)
return header_role;
// If there are no other cells on that row, then it is a column header.
- return kColumnHeaderRole;
+ return ax::mojom::Role::kColumnHeader;
}
AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index,
@@ -3098,7 +3180,7 @@ AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index,
return nullptr;
}
-bool AXLayoutObject::FindAllTableCellsWithRole(AccessibilityRole role,
+bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::Role role,
AXObjectVector& cells) const {
LayoutObject* layout_object = GetLayoutObject();
if (!layout_object || !layout_object->IsTable())
@@ -3129,12 +3211,12 @@ bool AXLayoutObject::FindAllTableCellsWithRole(AccessibilityRole role,
}
void AXLayoutObject::ColumnHeaders(AXObjectVector& headers) const {
- if (!FindAllTableCellsWithRole(kColumnHeaderRole, headers))
+ if (!FindAllTableCellsWithRole(ax::mojom::Role::kColumnHeader, headers))
AXNodeObject::ColumnHeaders(headers);
}
void AXLayoutObject::RowHeaders(AXObjectVector& headers) const {
- if (!FindAllTableCellsWithRole(kRowHeaderRole, headers))
+ if (!FindAllTableCellsWithRole(ax::mojom::Role::kRowHeader, headers))
AXNodeObject::RowHeaders(headers);
}
@@ -3147,7 +3229,7 @@ AXObject* AXLayoutObject::HeaderObject() const {
for (LayoutTableCell* cell = row->FirstCell(); cell;
cell = cell->NextCell()) {
AXObject* ax_cell = AXObjectCache().GetOrCreate(cell);
- if (ax_cell && ax_cell->RoleValue() == kRowHeaderRole)
+ if (ax_cell && ax_cell->RoleValue() == ax::mojom::Role::kRowHeader)
return ax_cell;
}
@@ -3182,7 +3264,7 @@ bool AXLayoutObject::IsTabItemSelected() const {
AXObject* tab_panel = AXObjectCache().GetOrCreate(element);
// A tab item should only control tab panels.
- if (!tab_panel || tab_panel->RoleValue() != kTabPanelRole)
+ if (!tab_panel || tab_panel->RoleValue() != ax::mojom::Role::kTabPanel)
continue;
AXObject* check_focus_element = focused_element;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
index f7b2597c2ee..45384248ffa 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -56,8 +56,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
LayoutObject* GetLayoutObject() const final { return layout_object_; }
LayoutBoxModelObject* GetLayoutBoxModelObject() const;
ScrollableArea* GetScrollableAreaIfScrollable() const final;
- AccessibilityRole DetermineAccessibilityRole() override;
- AccessibilityRole NativeAccessibilityRoleIgnoringAria() const override;
+ ax::mojom::Role DetermineAccessibilityRole() override;
+ ax::mojom::Role NativeRoleIgnoringAria() const override;
// If this is an anonymous block, returns the node of its containing layout
// block, otherwise returns the node of this layout object.
@@ -107,8 +107,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
float FontSize() const final;
String ImageDataUrl(const IntSize& max_size) const final;
String GetText() const override;
- AccessibilityTextDirection GetTextDirection() const final;
- AXTextPosition GetTextPosition() const final;
+ ax::mojom::TextDirection GetTextDirection() const final;
+ ax::mojom::TextPosition GetTextPosition() const final;
int TextLength() const override;
TextStyle GetTextStyle() const final;
KURL Url() const override;
@@ -125,7 +125,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void AriaDescribedbyElements(AXObjectVector&) const override;
void AriaOwnsElements(AXObjectVector&) const override;
- AXHasPopup HasPopup() const override;
+ ax::mojom::HasPopup HasPopup() const override;
bool SupportsARIADragging() const override;
bool SupportsARIADropping() const override;
bool SupportsARIAFlowTo() const override;
@@ -139,7 +139,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
@@ -202,7 +202,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
unsigned RowIndex() const override; // Also for a table row.
unsigned ColumnSpan() const override;
unsigned RowSpan() const override;
- SortDirection GetSortDirection() const override;
+ ax::mojom::SortDirection GetSortDirection() const override;
// For a table row or column.
AXObject* HeaderObject() const override;
@@ -224,9 +224,9 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void AddRemoteSVGChildren();
void AddTableChildren();
void AddInlineTextBoxChildren(bool force);
- AccessibilityRole DetermineTableCellRole() const;
- AccessibilityRole DetermineTableRowRole() const;
- bool FindAllTableCellsWithRole(AccessibilityRole, AXObjectVector&) const;
+ ax::mojom::Role DetermineTableCellRole() const;
+ ax::mojom::Role DetermineTableRowRole() const;
+ bool FindAllTableCellsWithRole(ax::mojom::Role, AXObjectVector&) const;
LayoutRect ComputeElementRect() const;
AXSelection TextControlSelection() const;
@@ -236,6 +236,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool CanIgnoreTextAsEmpty() const;
bool CanIgnoreSpaceNextTo(LayoutObject*, bool is_after) const;
bool HasAriaCellRole(Element*) const;
+ bool IsPlaceholder() const;
bool is_autofill_available_;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc
index 59f9b75a3a8..98d081036a6 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc
@@ -59,10 +59,10 @@ bool AXList::IsDescriptionList() const {
return node && node->HasTagName(dlTag);
}
-AccessibilityRole AXList::RoleValue() const {
+ax::mojom::Role AXList::RoleValue() const {
if (IsDescriptionList())
- return kDescriptionListRole;
+ return ax::mojom::Role::kDescriptionList;
- return kListRole;
+ return ax::mojom::Role::kList;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.h
index b07f0712680..f2211e18772 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.h
@@ -46,7 +46,7 @@ class AXList final : public AXLayoutObject {
bool IsList() const override { return true; }
- AccessibilityRole RoleValue() const final;
+ ax::mojom::Role RoleValue() const final;
private:
bool IsDescriptionList() const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc
index c34efafd2c6..083bad904a2 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc
@@ -50,11 +50,11 @@ AXListBox* AXListBox::Create(LayoutObject* layout_object,
return new AXListBox(layout_object, ax_object_cache);
}
-AccessibilityRole AXListBox::DetermineAccessibilityRole() {
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ax::mojom::Role AXListBox::DetermineAccessibilityRole() {
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
- return kListBoxRole;
+ return ax::mojom::Role::kListBox;
}
AXObject* AXListBox::ActiveDescendant() {
@@ -84,8 +84,8 @@ void AXListBox::ActiveIndexChanged() {
if (!select->IsFocused())
return;
- AXObjectCache().PostNotification(
- this, AXObjectCacheImpl::kAXActiveDescendantChanged);
+ AXObjectCache().PostNotification(this,
+ ax::mojom::Event::kActiveDescendantChanged);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
index e79171d3b6b..c4ddb67784e 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
@@ -44,7 +44,7 @@ class AXListBox final : public AXLayoutObject {
static AXListBox* Create(LayoutObject*, AXObjectCacheImpl&);
~AXListBox() override;
- AccessibilityRole DetermineAccessibilityRole() final;
+ ax::mojom::Role DetermineAccessibilityRole() final;
bool IsAXListBox() const override { return true; }
AXObject* ActiveDescendant() final;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
index c0ce1e480e3..de06a56fd1c 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
@@ -49,8 +49,8 @@ AXListBoxOption* AXListBoxOption::Create(LayoutObject* layout_object,
return new AXListBoxOption(layout_object, ax_object_cache);
}
-AccessibilityRole AXListBoxOption::DetermineAccessibilityRole() {
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ax::mojom::Role AXListBoxOption::DetermineAccessibilityRole() {
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
// http://www.w3.org/TR/wai-aria/complete#presentation
@@ -59,9 +59,9 @@ AccessibilityRole AXListBoxOption::DetermineAccessibilityRole() {
// does not cause the content contained within the element to be removed from
// the accessibility tree.
if (IsParentPresentationalRole())
- return kStaticTextRole;
+ return ax::mojom::Role::kStaticText;
- return kListBoxOptionRole;
+ return ax::mojom::Role::kListBoxOption;
}
bool AXListBoxOption::IsParentPresentationalRole() const {
@@ -111,7 +111,7 @@ bool AXListBoxOption::ComputeAccessibilityIsIgnored(
String AXListBoxOption::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
// If nameSources is non-null, relatedObjects is used in filling it in, so it
@@ -129,7 +129,7 @@ String AXListBoxOption::TextAlternative(bool recursive,
if (found_text_alternative && !name_sources)
return text_alternative;
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
text_alternative = ToHTMLOptionElement(GetNode())->DisplayLabel();
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative));
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.h
index ef2129317de..07ed3c8f526 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.h
@@ -47,7 +47,7 @@ class AXListBoxOption final : public AXLayoutObject {
~AXListBoxOption() override;
bool IsAXListBoxOption() const override { return true; }
- AccessibilityRole DetermineAccessibilityRole() final;
+ ax::mojom::Role DetermineAccessibilityRole() final;
AccessibilitySelectedState IsSelected() const override;
bool IsSelectedOptionActive() const override;
bool OnNativeSetSelectedAction(bool) override;
@@ -55,7 +55,7 @@ class AXListBoxOption final : public AXLayoutObject {
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
index 66bef28d1da..4bc852fd8ee 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
@@ -59,6 +59,10 @@ AXObject* AccessibilityMediaControl::Create(
case kMediaSlider:
return AccessibilityMediaTimeline::Create(layout_object, ax_object_cache);
+ case kMediaVolumeSlider:
+ return AccessibilityMediaVolumeSlider::Create(layout_object,
+ ax_object_cache);
+
case kMediaCurrentTimeDisplay:
case kMediaTimeRemainingDisplay:
return AccessibilityMediaTimeDisplay::Create(layout_object,
@@ -79,7 +83,6 @@ AXObject* AccessibilityMediaControl::Create(
case kMediaTimelineContainer:
case kMediaTrackSelectionCheckmark:
case kMediaVolumeSliderContainer:
- case kMediaVolumeSlider:
case kMediaVolumeSliderThumb:
case kMediaExitFullscreenButton:
case kMediaCastOffButton:
@@ -93,6 +96,7 @@ AXObject* AccessibilityMediaControl::Create(
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
case kMediaDisplayCutoutFullscreenButton:
+ case kMediaAnimatedArrowContainer:
return new AccessibilityMediaControl(layout_object, ax_object_cache);
}
@@ -108,28 +112,21 @@ MediaControlElementType AccessibilityMediaControl::ControlType() const {
GetLayoutObject()->GetNode());
}
-bool AccessibilityMediaControl::OnNativeScrollToGlobalPointAction(
- const IntPoint& point) const {
+bool AccessibilityMediaControl::InternalSetAccessibilityFocusAction() {
MediaControlElementsHelper::NotifyMediaControlAccessibleFocus(GetElement());
- return AXLayoutObject::OnNativeScrollToGlobalPointAction(point);
+ return AXLayoutObject::InternalSetAccessibilityFocusAction();
}
-bool AccessibilityMediaControl::OnNativeScrollToMakeVisibleAction() const {
- MediaControlElementsHelper::NotifyMediaControlAccessibleFocus(GetElement());
- return AXLayoutObject::OnNativeScrollToMakeVisibleAction();
-}
-
-bool AccessibilityMediaControl::OnNativeScrollToMakeVisibleWithSubFocusAction(
- const IntRect& rect) const {
- MediaControlElementsHelper::NotifyMediaControlAccessibleFocus(GetElement());
- return AXLayoutObject::OnNativeScrollToMakeVisibleWithSubFocusAction(rect);
+bool AccessibilityMediaControl::InternalClearAccessibilityFocusAction() {
+ MediaControlElementsHelper::NotifyMediaControlAccessibleBlur(GetElement());
+ return AXLayoutObject::InternalClearAccessibilityFocusAction();
}
String AccessibilityMediaControl::TextAlternative(
bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
switch (ControlType()) {
@@ -169,10 +166,10 @@ String AccessibilityMediaControl::TextAlternative(
case kMediaTrackSelectionCheckmark:
case kMediaControlsPanel:
case kMediaVolumeSliderContainer:
- case kMediaVolumeSlider:
case kMediaVolumeSliderThumb:
case kMediaOverflowList:
case kMediaScrubbingMessage:
+ case kMediaAnimatedArrowContainer:
return QueryString(WebLocalizedString::kAXMediaDefault);
case kMediaEnterPictureInPictureButton:
return QueryString(
@@ -184,6 +181,7 @@ String AccessibilityMediaControl::TextAlternative(
return QueryString(
WebLocalizedString::kAXMediaDisplayCutoutFullscreenButton);
case kMediaSlider:
+ case kMediaVolumeSlider:
NOTREACHED();
return QueryString(WebLocalizedString::kAXMediaDefault);
}
@@ -193,62 +191,49 @@ String AccessibilityMediaControl::TextAlternative(
}
String AccessibilityMediaControl::Description(
- AXNameFrom name_from,
- AXDescriptionFrom& description_from,
+ ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
AXObjectVector* description_objects) const {
switch (ControlType()) {
+ case kMediaCurrentTimeDisplay:
+ return QueryString(WebLocalizedString::kAXMediaCurrentTimeDisplayHelp);
+ case kMediaTimeRemainingDisplay:
+ return QueryString(WebLocalizedString::kAXMediaTimeRemainingDisplayHelp);
+ case kMediaOverflowButton:
+ return QueryString(WebLocalizedString::kAXMediaOverflowButtonHelp);
+ // The following descriptions are repeats of their respective titles. When
+ // read by accessibility, we get the same thing said twice, with no value
+ // added. So instead, we just return an empty string.
case kMediaEnterFullscreenButton:
- return QueryString(WebLocalizedString::kAXMediaEnterFullscreenButtonHelp);
case kMediaExitFullscreenButton:
- return QueryString(WebLocalizedString::kAXMediaExitFullscreenButtonHelp);
+ case kMediaDisplayCutoutFullscreenButton:
case kMediaMuteButton:
- return QueryString(WebLocalizedString::kAXMediaMuteButtonHelp);
- case kMediaPlayButton:
- return QueryString(WebLocalizedString::kAXMediaPlayButtonHelp);
case kMediaUnMuteButton:
- return QueryString(WebLocalizedString::kAXMediaUnMuteButtonHelp);
+ case kMediaPlayButton:
case kMediaPauseButton:
- return QueryString(WebLocalizedString::kAXMediaPauseButtonHelp);
- case kMediaCurrentTimeDisplay:
- return QueryString(WebLocalizedString::kAXMediaCurrentTimeDisplayHelp);
- case kMediaTimeRemainingDisplay:
- return QueryString(WebLocalizedString::kAXMediaTimeRemainingDisplayHelp);
case kMediaShowClosedCaptionsButton:
- return QueryString(
- WebLocalizedString::kAXMediaShowClosedCaptionsButtonHelp);
case kMediaHideClosedCaptionsButton:
- return QueryString(
- WebLocalizedString::kAXMediaHideClosedCaptionsButtonHelp);
case kMediaCastOffButton:
case kMediaOverlayCastOffButton:
- return QueryString(WebLocalizedString::kAXMediaCastOffButtonHelp);
case kMediaCastOnButton:
case kMediaOverlayCastOnButton:
- return QueryString(WebLocalizedString::kAXMediaCastOnButtonHelp);
- case kMediaOverflowButton:
- return QueryString(WebLocalizedString::kAXMediaOverflowButtonHelp);
case kMediaEnterPictureInPictureButton:
- return QueryString(
- WebLocalizedString::kAXMediaEnterPictureInPictureButtonHelp);
case kMediaExitPictureInPictureButton:
- return QueryString(
- WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp);
- case kMediaDisplayCutoutFullscreenButton:
- return QueryString(
- WebLocalizedString::kAXMediaDisplayCutoutFullscreenButtonHelp);
+ return "";
case kMediaSliderThumb:
case kMediaTextTrackList:
case kMediaTimelineContainer:
case kMediaTrackSelectionCheckmark:
case kMediaControlsPanel:
case kMediaVolumeSliderContainer:
- case kMediaVolumeSlider:
case kMediaVolumeSliderThumb:
case kMediaOverflowList:
case kMediaDownloadButton:
case kMediaScrubbingMessage:
+ case kMediaAnimatedArrowContainer:
return QueryString(WebLocalizedString::kAXMediaDefault);
case kMediaSlider:
+ case kMediaVolumeSlider:
NOTREACHED();
return QueryString(WebLocalizedString::kAXMediaDefault);
}
@@ -267,7 +252,7 @@ bool AccessibilityMediaControl::ComputeAccessibilityIsIgnored(
return AccessibilityIsIgnoredByDefault(ignored_reasons);
}
-AccessibilityRole AccessibilityMediaControl::RoleValue() const {
+ax::mojom::Role AccessibilityMediaControl::RoleValue() const {
switch (ControlType()) {
case kMediaEnterFullscreenButton:
case kMediaExitFullscreenButton:
@@ -286,32 +271,33 @@ AccessibilityRole AccessibilityMediaControl::RoleValue() const {
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
case kMediaDisplayCutoutFullscreenButton:
- return kButtonRole;
+ return ax::mojom::Role::kButton;
case kMediaTimelineContainer:
case kMediaVolumeSliderContainer:
case kMediaTextTrackList:
case kMediaOverflowList:
- return kGroupRole;
+ return ax::mojom::Role::kGroup;
case kMediaControlsPanel:
case kMediaCurrentTimeDisplay:
case kMediaTimeRemainingDisplay:
case kMediaSliderThumb:
case kMediaTrackSelectionCheckmark:
- case kMediaVolumeSlider:
case kMediaVolumeSliderThumb:
case kMediaScrubbingMessage:
- return kUnknownRole;
+ case kMediaAnimatedArrowContainer:
+ return ax::mojom::Role::kUnknown;
case kMediaSlider:
+ case kMediaVolumeSlider:
// Not using AccessibilityMediaControl.
NOTREACHED();
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
}
NOTREACHED();
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
}
//
@@ -331,7 +317,7 @@ String AXMediaControlsContainer::TextAlternative(
bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
return QueryString(IsControllingVideoElement()
@@ -340,8 +326,8 @@ String AXMediaControlsContainer::TextAlternative(
}
String AXMediaControlsContainer::Description(
- AXNameFrom name_from,
- AXDescriptionFrom& description_from,
+ ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
AXObjectVector* description_objects) const {
return QueryString(IsControllingVideoElement()
? WebLocalizedString::kAXMediaVideoElementHelp
@@ -374,8 +360,8 @@ AXObject* AccessibilityMediaTimeline::Create(
}
String AccessibilityMediaTimeline::Description(
- AXNameFrom name_from,
- AXDescriptionFrom& description_from,
+ ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
AXObjectVector* description_objects) const {
return QueryString(IsControllingVideoElement()
? WebLocalizedString::kAXMediaVideoSliderHelp
@@ -383,6 +369,37 @@ String AccessibilityMediaTimeline::Description(
}
//
+// AccessibilityMediaVolumeSlider
+
+AccessibilityMediaVolumeSlider::AccessibilityMediaVolumeSlider(
+ LayoutObject* layout_object,
+ AXObjectCacheImpl& ax_object_cache)
+ : AXSlider(layout_object, ax_object_cache) {}
+
+AXObject* AccessibilityMediaVolumeSlider::Create(
+ LayoutObject* layout_object,
+ AXObjectCacheImpl& ax_object_cache) {
+ return new AccessibilityMediaVolumeSlider(layout_object, ax_object_cache);
+}
+
+String AccessibilityMediaVolumeSlider::Description(
+ ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
+ AXObjectVector* description_objects) const {
+ return QueryString(WebLocalizedString::kAXMediaVolumeSliderHelp);
+}
+
+bool AccessibilityMediaVolumeSlider::InternalSetAccessibilityFocusAction() {
+ MediaControlElementsHelper::NotifyMediaControlAccessibleFocus(GetElement());
+ return AXSlider::InternalSetAccessibilityFocusAction();
+}
+
+bool AccessibilityMediaVolumeSlider::InternalClearAccessibilityFocusAction() {
+ MediaControlElementsHelper::NotifyMediaControlAccessibleBlur(GetElement());
+ return AXSlider::InternalClearAccessibilityFocusAction();
+}
+
+//
// AccessibilityMediaTimeDisplay
AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(
@@ -412,7 +429,7 @@ String AccessibilityMediaTimeDisplay::TextAlternative(
bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
if (ControlType() == kMediaCurrentTimeDisplay)
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.h
index 17f1913e57f..fc7c71c0424 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.h
@@ -42,22 +42,20 @@ class AccessibilityMediaControl : public AXLayoutObject {
static AXObject* Create(LayoutObject*, AXObjectCacheImpl&);
~AccessibilityMediaControl() override = default;
- AccessibilityRole RoleValue() const override;
+ ax::mojom::Role RoleValue() const override;
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
- String Description(AXNameFrom,
- AXDescriptionFrom&,
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
AXObjectVector* description_objects) const override;
- bool OnNativeScrollToGlobalPointAction(const IntPoint&) const override;
- bool OnNativeScrollToMakeVisibleAction() const override;
- bool OnNativeScrollToMakeVisibleWithSubFocusAction(
- const IntRect&) const override;
+ bool InternalSetAccessibilityFocusAction() override;
+ bool InternalClearAccessibilityFocusAction() override;
protected:
AccessibilityMediaControl(LayoutObject*, AXObjectCacheImpl&);
@@ -72,8 +70,8 @@ class AccessibilityMediaTimeline final : public AXSlider {
static AXObject* Create(LayoutObject*, AXObjectCacheImpl&);
~AccessibilityMediaTimeline() override = default;
- String Description(AXNameFrom,
- AXDescriptionFrom&,
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
AXObjectVector* description_objects) const override;
private:
@@ -82,21 +80,41 @@ class AccessibilityMediaTimeline final : public AXSlider {
DISALLOW_COPY_AND_ASSIGN(AccessibilityMediaTimeline);
};
+class AccessibilityMediaVolumeSlider final : public AXSlider {
+ public:
+ static AXObject* Create(LayoutObject*, AXObjectCacheImpl&);
+ ~AccessibilityMediaVolumeSlider() override = default;
+
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
+ AXObjectVector* description_objects) const override;
+
+ bool InternalSetAccessibilityFocusAction() override;
+ bool InternalClearAccessibilityFocusAction() override;
+
+ private:
+ AccessibilityMediaVolumeSlider(LayoutObject*, AXObjectCacheImpl&);
+
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityMediaVolumeSlider);
+};
+
class AXMediaControlsContainer final : public AccessibilityMediaControl {
public:
static AXObject* Create(LayoutObject*, AXObjectCacheImpl&);
~AXMediaControlsContainer() override = default;
- AccessibilityRole RoleValue() const override { return kToolbarRole; }
+ ax::mojom::Role RoleValue() const override {
+ return ax::mojom::Role::kToolbar;
+ }
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
- String Description(AXNameFrom,
- AXDescriptionFrom&,
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
AXObjectVector* description_objects) const override;
private:
@@ -111,13 +129,15 @@ class AccessibilityMediaTimeDisplay final : public AccessibilityMediaControl {
static AXObject* Create(LayoutObject*, AXObjectCacheImpl&);
~AccessibilityMediaTimeDisplay() override = default;
- AccessibilityRole RoleValue() const override { return kStaticTextRole; }
+ ax::mojom::Role RoleValue() const override {
+ return ax::mojom::Role::kStaticText;
+ }
String StringValue() const override;
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index 85ee9f64206..1f294af0880 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -41,11 +41,11 @@ AXMenuList* AXMenuList::Create(LayoutMenuList* layout_object,
return new AXMenuList(layout_object, ax_object_cache);
}
-AccessibilityRole AXMenuList::DetermineAccessibilityRole() {
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ax::mojom::Role AXMenuList::DetermineAccessibilityRole() {
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
- return kPopUpButtonRole;
+ return ax::mojom::Role::kPopUpButton;
}
bool AXMenuList::OnNativeClickAction() {
@@ -78,7 +78,7 @@ void AXMenuList::AddChildren() {
AXObjectCacheImpl& cache = AXObjectCache();
- AXObject* list = cache.GetOrCreate(kMenuListPopupRole);
+ AXObject* list = cache.GetOrCreate(ax::mojom::Role::kMenuListPopup);
if (!list)
return;
@@ -127,7 +127,7 @@ void AXMenuList::DidUpdateActiveOption(int option_index) {
}
AXObjectCache().PostNotification(this,
- AXObjectCacheImpl::kAXMenuListValueChanged);
+ ax::mojom::Event::kMenuListValueChanged);
}
void AXMenuList::DidShowPopup() {
@@ -146,8 +146,7 @@ void AXMenuList::DidHidePopup() {
popup->DidHide();
if (GetNode() && GetNode()->IsFocused())
- AXObjectCache().PostNotification(
- this, AXObjectCacheImpl::kAXFocusedUIElementChanged);
+ AXObjectCache().PostNotification(this, ax::mojom::Event::kFocus);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
index bafcc00afa5..a54dc3177da 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
@@ -38,7 +38,6 @@ class AXMenuList final : public AXLayoutObject {
public:
static AXMenuList* Create(LayoutMenuList* layout_object, AXObjectCacheImpl&);
- bool IsCollapsed() const override;
AccessibilityExpanded IsExpanded() const final;
bool OnNativeClickAction() override;
void ClearChildren() override;
@@ -53,10 +52,12 @@ class AXMenuList final : public AXLayoutObject {
AXMenuList(LayoutMenuList*, AXObjectCacheImpl&);
bool IsMenuList() const override { return true; }
- AccessibilityRole DetermineAccessibilityRole() final;
+ ax::mojom::Role DetermineAccessibilityRole() final;
void AddChildren() override;
+ bool IsCollapsed() const;
+
DISALLOW_COPY_AND_ASSIGN(AXMenuList);
};
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
index a6b3ae05669..57b987bbdcd 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc
@@ -55,16 +55,16 @@ LocalFrameView* AXMenuListOption::DocumentFrameView() const {
return element_->GetDocument().View();
}
-AccessibilityRole AXMenuListOption::RoleValue() const {
+ax::mojom::Role AXMenuListOption::RoleValue() const {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role.IsEmpty())
- return kMenuListOptionRole;
+ return ax::mojom::Role::kMenuListOption;
- AccessibilityRole role = AriaRoleToWebCoreRole(aria_role);
- if (role)
+ ax::mojom::Role role = AriaRoleToWebCoreRole(aria_role);
+ if (role != ax::mojom::Role::kUnknown)
return role;
- return kMenuListOptionRole;
+ return ax::mojom::Role::kMenuListOption;
}
Element* AXMenuListOption::ActionElement() const {
@@ -79,6 +79,8 @@ AXObject* AXMenuListOption::ComputeParent() const {
if (!select)
return nullptr;
AXObject* select_ax_object = AXObjectCache().GetOrCreate(select);
+ if (!select_ax_object)
+ return nullptr;
// This happens if the <select> is not rendered. Return it and move on.
if (!select_ax_object->IsMenuList())
@@ -178,7 +180,7 @@ void AXMenuListOption::GetRelativeBounds(AXObject** out_container,
String AXMenuListOption::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
// If nameSources is non-null, relatedObjects is used in filling it in, so it
@@ -196,7 +198,7 @@ String AXMenuListOption::TextAlternative(bool recursive,
if (found_text_alternative && !name_sources)
return text_alternative;
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
text_alternative = element_->DisplayLabel();
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative));
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
index 8d60d311093..cfb60cb8751 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h
@@ -55,7 +55,7 @@ class AXMenuListOption final : public AXMockObject {
void Detach() override;
bool IsDetached() const override { return !element_; }
LocalFrameView* DocumentFrameView() const override;
- AccessibilityRole RoleValue() const override;
+ ax::mojom::Role RoleValue() const override;
bool CanHaveChildren() const override { return false; }
AXObject* ComputeParent() const override;
@@ -72,7 +72,7 @@ class AXMenuListOption final : public AXMockObject {
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
index bfb71651b0e..a1bf9c85429 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc
@@ -44,7 +44,7 @@ bool AXMenuListPopup::IsOffScreen() const {
if (!parent_)
return true;
- return parent_->IsCollapsed();
+ return parent_->IsExpanded() == kExpandedCollapsed;
}
AXRestriction AXMenuListPopup::Restriction() const {
@@ -135,25 +135,24 @@ void AXMenuListPopup::DidUpdateActiveOption(int option_index,
old_index < static_cast<int>(children_.size())) {
AXObject* previous_child = children_[old_index].Get();
cache.PostNotification(previous_child,
- AXObjectCacheImpl::kAXMenuListItemUnselected);
+ ax::mojom::Event::kMenuListItemSelected);
}
if (option_index >= 0 && option_index < static_cast<int>(children_.size())) {
AXObject* child = children_[option_index].Get();
- cache.PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
- cache.PostNotification(this, AXObjectCacheImpl::kAXActiveDescendantChanged);
- cache.PostNotification(child, AXObjectCacheImpl::kAXMenuListItemSelected);
+ cache.PostNotification(this, ax::mojom::Event::kChildrenChanged);
+ cache.PostNotification(this, ax::mojom::Event::kActiveDescendantChanged);
+ cache.PostNotification(child, ax::mojom::Event::kMenuListItemSelected);
}
}
void AXMenuListPopup::DidHide() {
AXObjectCacheImpl& cache = AXObjectCache();
AXObject* descendant = ActiveDescendant();
- cache.PostNotification(this, AXObjectCacheImpl::kAXHide);
+ cache.PostNotification(this, ax::mojom::Event::kHide);
if (descendant) {
- cache.PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
- cache.PostNotification(descendant,
- AXObjectCacheImpl::kAXMenuListItemUnselected);
+ cache.PostNotification(this, ax::mojom::Event::kChildrenChanged);
+ cache.PostNotification(descendant, ax::mojom::Event::kMenuListItemSelected);
}
}
@@ -162,14 +161,13 @@ void AXMenuListPopup::DidShow() {
AddChildren();
AXObjectCacheImpl& cache = AXObjectCache();
- cache.PostNotification(this, AXObjectCacheImpl::kAXShow);
+ cache.PostNotification(this, ax::mojom::Event::kShow);
int selected_index = GetSelectedIndex();
if (selected_index >= 0 &&
selected_index < static_cast<int>(children_.size())) {
DidUpdateActiveOption(selected_index);
} else {
- cache.PostNotification(parent_,
- AXObjectCacheImpl::kAXFocusedUIElementChanged);
+ cache.PostNotification(parent_, ax::mojom::Event::kFocus);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
index 5c88b4143da..2625784fa6c 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
@@ -55,7 +55,9 @@ class AXMenuListPopup final : public AXMockObject {
bool IsMenuListPopup() const override { return true; }
- AccessibilityRole RoleValue() const override { return kMenuListPopupRole; }
+ ax::mojom::Role RoleValue() const override {
+ return ax::mojom::Role::kMenuListPopup;
+ }
bool IsVisible() const override;
bool OnNativeClickAction() override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 40cae4314eb..a73d98400e9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
+#include "third_party/blink/renderer/core/editing/position.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
@@ -87,7 +88,7 @@ const int kDefaultHeadingLevel = 2;
AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache)
: AXObject(ax_object_cache),
children_dirty_(false),
- native_role_(kUnknownRole),
+ native_role_(ax::mojom::Role::kUnknown),
node_(node) {}
AXNodeObject* AXNodeObject::Create(Node* node,
@@ -113,8 +114,7 @@ void AXNodeObject::AlterSliderOrSpinButtonValue(bool increase) {
value += increase ? step : -step;
OnNativeSetValueAction(String::Number(value));
- AXObjectCache().PostNotification(GetNode(),
- AXObjectCacheImpl::kAXValueChanged);
+ AXObjectCache().PostNotification(GetNode(), ax::mojom::Event::kValueChanged);
}
AXObject* AXNodeObject::ActiveDescendant() {
@@ -174,7 +174,7 @@ bool AXNodeObject::ComputeAccessibilityIsIgnored(
return true;
}
- if (role_ == kUnknownRole) {
+ if (role_ == ax::mojom::Role::kUnknown) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
@@ -188,18 +188,19 @@ static bool IsListElement(Node* node) {
}
static bool IsRequiredOwnedElement(AXObject* parent,
- AccessibilityRole current_role,
+ ax::mojom::Role current_role,
HTMLElement* current_element) {
Node* parent_node = parent->GetNode();
if (!parent_node || !parent_node->IsHTMLElement())
return false;
- if (current_role == kListItemRole)
+ if (current_role == ax::mojom::Role::kListItem)
return IsListElement(parent_node);
- if (current_role == kListMarkerRole)
+ if (current_role == ax::mojom::Role::kListMarker)
return IsHTMLLIElement(*parent_node);
- if (current_role == kMenuItemCheckBoxRole || current_role == kMenuItemRole ||
- current_role == kMenuItemRadioRole)
+ if (current_role == ax::mojom::Role::kMenuItemCheckBox ||
+ current_role == ax::mojom::Role::kMenuItem ||
+ current_role == ax::mojom::Role::kMenuItemRadio)
return IsHTMLMenuElement(*parent_node);
if (!current_element)
@@ -229,7 +230,7 @@ const AXObject* AXNodeObject::InheritsPresentationalRoleFrom() const {
// ARIA spec says that the user agent MUST apply an inherited role of
// presentation
// to any owned elements that do not have an explicit role defined.
- if (AriaRoleAttribute() != kUnknownRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
return nullptr;
AXObject* parent = ParentObject();
@@ -290,195 +291,200 @@ bool AXNodeObject::IsDescendantOfElementType(
// TODO(accessibility) This value is cached in native_role_ so it needs to
// be recached if anything it depends on change, such as IsClickable(),
// DataList(), aria-pressed, the parent's tag, role on an iframe, etc.
-AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
+ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
if (!GetNode())
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
// |HTMLAnchorElement| sets isLink only when it has hrefAttr.
if (GetNode()->IsLink())
- return kLinkRole;
+ return ax::mojom::Role::kLink;
if (IsHTMLAnchorElement(*GetNode())) {
// We assume that an anchor element is LinkRole if it has event listners
// even though it doesn't have hrefAttr.
if (IsClickable())
- return kLinkRole;
- return kAnchorRole;
+ return ax::mojom::Role::kLink;
+ return ax::mojom::Role::kAnchor;
}
if (IsHTMLButtonElement(*GetNode()))
return ButtonRoleType();
if (IsHTMLDetailsElement(*GetNode()))
- return kDetailsRole;
+ return ax::mojom::Role::kDetails;
if (IsHTMLSummaryElement(*GetNode())) {
ContainerNode* parent = FlatTreeTraversal::Parent(*GetNode());
if (parent && IsHTMLSlotElement(parent))
parent = FlatTreeTraversal::Parent(*parent);
if (parent && IsHTMLDetailsElement(parent))
- return kDisclosureTriangleRole;
- return kUnknownRole;
+ return ax::mojom::Role::kDisclosureTriangle;
+ return ax::mojom::Role::kUnknown;
}
if (const auto* input = ToHTMLInputElementOrNull(*GetNode())) {
const AtomicString& type = input->type();
if (input->DataList())
- return kTextFieldWithComboBoxRole;
+ return ax::mojom::Role::kTextFieldWithComboBox;
if (type == InputTypeNames::button) {
if ((GetNode()->parentNode() &&
IsHTMLMenuElement(GetNode()->parentNode())) ||
- (ParentObject() && ParentObject()->RoleValue() == kMenuRole))
- return kMenuItemRole;
+ (ParentObject() &&
+ ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
+ return ax::mojom::Role::kMenuItem;
return ButtonRoleType();
}
if (type == InputTypeNames::checkbox) {
if ((GetNode()->parentNode() &&
IsHTMLMenuElement(GetNode()->parentNode())) ||
- (ParentObject() && ParentObject()->RoleValue() == kMenuRole))
- return kMenuItemCheckBoxRole;
- return kCheckBoxRole;
+ (ParentObject() &&
+ ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
+ return ax::mojom::Role::kMenuItemCheckBox;
+ return ax::mojom::Role::kCheckBox;
}
if (type == InputTypeNames::date)
- return kDateRole;
+ return ax::mojom::Role::kDate;
if (type == InputTypeNames::datetime ||
type == InputTypeNames::datetime_local ||
type == InputTypeNames::month || type == InputTypeNames::week)
- return kDateTimeRole;
+ return ax::mojom::Role::kDateTime;
if (type == InputTypeNames::file)
- return kButtonRole;
+ return ax::mojom::Role::kButton;
if (type == InputTypeNames::radio) {
if ((GetNode()->parentNode() &&
IsHTMLMenuElement(GetNode()->parentNode())) ||
- (ParentObject() && ParentObject()->RoleValue() == kMenuRole))
- return kMenuItemRadioRole;
- return kRadioButtonRole;
+ (ParentObject() &&
+ ParentObject()->RoleValue() == ax::mojom::Role::kMenu))
+ return ax::mojom::Role::kMenuItemRadio;
+ return ax::mojom::Role::kRadioButton;
}
if (type == InputTypeNames::number)
- return kSpinButtonRole;
+ return ax::mojom::Role::kSpinButton;
if (input->IsTextButton())
return ButtonRoleType();
if (type == InputTypeNames::range)
- return kSliderRole;
+ return ax::mojom::Role::kSlider;
if (type == InputTypeNames::color)
- return kColorWellRole;
+ return ax::mojom::Role::kColorWell;
if (type == InputTypeNames::time)
- return kInputTimeRole;
- return kTextFieldRole;
+ return ax::mojom::Role::kInputTime;
+ return ax::mojom::Role::kTextField;
}
- if (auto* select_element = ToHTMLSelectElementOrNull(*GetNode()))
- return select_element->IsMultiple() ? kListBoxRole : kPopUpButtonRole;
+ if (auto* select_element = ToHTMLSelectElementOrNull(*GetNode())) {
+ return select_element->IsMultiple() ? ax::mojom::Role::kListBox
+ : ax::mojom::Role::kPopUpButton;
+ }
if (auto* option = ToHTMLOptionElementOrNull(*GetNode())) {
HTMLSelectElement* select_element = option->OwnerSelectElement();
return !select_element || select_element->IsMultiple()
- ? kListBoxOptionRole
- : kMenuListOptionRole;
+ ? ax::mojom::Role::kListBoxOption
+ : ax::mojom::Role::kMenuListOption;
}
if (IsHTMLTextAreaElement(*GetNode()))
- return kTextFieldRole;
+ return ax::mojom::Role::kTextField;
if (HeadingLevel())
- return kHeadingRole;
+ return ax::mojom::Role::kHeading;
if (IsHTMLDivElement(*GetNode()))
- return kGenericContainerRole;
+ return ax::mojom::Role::kGenericContainer;
if (IsHTMLMeterElement(*GetNode()))
- return kMeterRole;
+ return ax::mojom::Role::kMeter;
if (IsHTMLProgressElement(*GetNode()))
- return kProgressIndicatorRole;
+ return ax::mojom::Role::kProgressIndicator;
if (IsHTMLOutputElement(*GetNode()))
- return kStatusRole;
+ return ax::mojom::Role::kStatus;
if (IsHTMLParagraphElement(*GetNode()))
- return kParagraphRole;
+ return ax::mojom::Role::kParagraph;
if (IsHTMLLabelElement(*GetNode()))
- return kLabelRole;
+ return ax::mojom::Role::kLabelText;
if (IsHTMLLegendElement(*GetNode()))
- return kLegendRole;
+ return ax::mojom::Role::kLegend;
if (IsHTMLRubyElement(*GetNode()))
- return kRubyRole;
+ return ax::mojom::Role::kRuby;
if (IsHTMLDListElement(*GetNode()))
- return kDescriptionListRole;
+ return ax::mojom::Role::kDescriptionList;
if (IsHTMLAudioElement(*GetNode()))
- return kAudioRole;
+ return ax::mojom::Role::kAudio;
if (IsHTMLVideoElement(*GetNode()))
- return kVideoRole;
+ return ax::mojom::Role::kVideo;
if (GetNode()->HasTagName(ddTag))
- return kDescriptionListDetailRole;
+ return ax::mojom::Role::kDescriptionListDetail;
if (GetNode()->HasTagName(dtTag))
- return kDescriptionListTermRole;
+ return ax::mojom::Role::kDescriptionListTerm;
if (GetNode()->nodeName() == "math")
- return kMathRole;
+ return ax::mojom::Role::kMath;
if (GetNode()->HasTagName(rpTag) || GetNode()->HasTagName(rtTag))
- return kAnnotationRole;
+ return ax::mojom::Role::kAnnotation;
if (IsHTMLFormElement(*GetNode()))
- return kFormRole;
+ return ax::mojom::Role::kForm;
if (GetNode()->HasTagName(abbrTag))
- return kAbbrRole;
+ return ax::mojom::Role::kAbbr;
if (GetNode()->HasTagName(articleTag))
- return kArticleRole;
+ return ax::mojom::Role::kArticle;
if (GetNode()->HasTagName(delTag))
- return kContentDeletionRole;
+ return ax::mojom::Role::kContentDeletion;
if (GetNode()->HasTagName(insTag))
- return kContentInsertionRole;
+ return ax::mojom::Role::kContentInsertion;
if (GetNode()->HasTagName(mainTag))
- return kMainRole;
+ return ax::mojom::Role::kMain;
if (GetNode()->HasTagName(markTag))
- return kMarkRole;
+ return ax::mojom::Role::kMark;
if (GetNode()->HasTagName(navTag))
- return kNavigationRole;
+ return ax::mojom::Role::kNavigation;
if (GetNode()->HasTagName(asideTag))
- return kComplementaryRole;
+ return ax::mojom::Role::kComplementary;
if (GetNode()->HasTagName(preTag))
- return kPreRole;
+ return ax::mojom::Role::kPre;
if (GetNode()->HasTagName(sectionTag))
- return kRegionRole;
+ return ax::mojom::Role::kRegion;
// TODO(accessibility): http://crbug.com/873118
if (GetNode()->HasTagName(addressTag))
- return kContentInfoRole;
+ return ax::mojom::Role::kContentInfo;
if (IsHTMLDialogElement(*GetNode()))
- return kDialogRole;
+ return ax::mojom::Role::kDialog;
// The HTML element should not be exposed as an element. That's what the
// LayoutView element does.
if (IsHTMLHtmlElement(*GetNode()))
- return kIgnoredRole;
+ return ax::mojom::Role::kIgnored;
// Treat <iframe> and <frame> the same.
if (IsHTMLIFrameElement(*GetNode()) || IsHTMLFrameElement(*GetNode())) {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role == "none" || aria_role == "presentation")
- return kIframePresentationalRole;
- return kIframeRole;
+ return ax::mojom::Role::kIframePresentational;
+ return ax::mojom::Role::kIframe;
}
// There should only be one banner/contentInfo per page. If header/footer are
@@ -486,55 +492,57 @@ AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
// whole page's banner/contentInfo but as a generic container role.
if (GetNode()->HasTagName(headerTag)) {
if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed()))
- return kGenericContainerRole;
- return kBannerRole;
+ return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::Role::kBanner;
}
if (GetNode()->HasTagName(footerTag)) {
if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed()))
- return kGenericContainerRole;
- return kFooterRole;
+ return ax::mojom::Role::kGenericContainer;
+ return ax::mojom::Role::kFooter;
}
if (GetNode()->HasTagName(blockquoteTag))
- return kBlockquoteRole;
+ return ax::mojom::Role::kBlockquote;
if (GetNode()->HasTagName(captionTag))
- return kCaptionRole;
+ return ax::mojom::Role::kCaption;
if (GetNode()->HasTagName(figcaptionTag))
- return kFigcaptionRole;
+ return ax::mojom::Role::kFigcaption;
if (GetNode()->HasTagName(figureTag))
- return kFigureRole;
+ return ax::mojom::Role::kFigure;
if (GetNode()->nodeName() == "TIME")
- return kTimeRole;
+ return ax::mojom::Role::kTime;
if (IsEmbeddedObject())
- return kEmbeddedObjectRole;
+ return ax::mojom::Role::kEmbeddedObject;
if (IsHTMLHRElement(*GetNode()))
- return kSplitterRole;
+ return ax::mojom::Role::kSplitter;
if (IsFieldset())
- return kGroupRole;
+ return ax::mojom::Role::kGroup;
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
}
-AccessibilityRole AXNodeObject::DetermineAccessibilityRole() {
+ax::mojom::Role AXNodeObject::DetermineAccessibilityRole() {
if (!GetNode())
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
- native_role_ = NativeAccessibilityRoleIgnoringAria();
+ native_role_ = NativeRoleIgnoringAria();
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
if (GetNode()->IsTextNode())
- return kStaticTextRole;
+ return ax::mojom::Role::kStaticText;
- return native_role_ == kUnknownRole ? kGenericContainerRole : native_role_;
+ return native_role_ == ax::mojom::Role::kUnknown
+ ? ax::mojom::Role::kGenericContainer
+ : native_role_;
}
void AXNodeObject::AccessibilityChildrenFromAOMProperty(
@@ -563,8 +571,9 @@ bool AXNodeObject::IsMultiline() const {
if (!node)
return false;
- const AccessibilityRole role = RoleValue();
- const bool is_edit_box = role == kSearchBoxRole || role == kTextFieldRole;
+ const ax::mojom::Role role = RoleValue();
+ const bool is_edit_box = role == ax::mojom::Role::kSearchBox ||
+ role == ax::mojom::Role::kTextField;
if (!IsEditable() && !is_edit_box)
return false; // Doesn't support multiline.
@@ -609,11 +618,11 @@ bool AXNodeObject::IsTextControl() const {
return true;
switch (RoleValue()) {
- case kTextFieldRole:
- case kTextFieldWithComboBoxRole:
- case kSearchBoxRole:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kSearchBox:
return true;
- case kSpinButtonRole:
+ case ax::mojom::Role::kSpinButton:
// When it's a native spin button, it behaves like a text box, i.e. users
// can type in it and navigate around using cursors.
if (const auto* input = ToHTMLInputElementOrNull(*GetNode())) {
@@ -669,7 +678,7 @@ static Element* SiblingWithAriaRole(String role, Node* node) {
}
Element* AXNodeObject::MenuItemElementForMenu() const {
- if (AriaRoleAttribute() != kMenuRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kMenu)
return nullptr;
return SiblingWithAriaRole("menuitem", GetNode());
@@ -757,7 +766,7 @@ bool AXNodeObject::IsFieldset() const {
}
bool AXNodeObject::IsHeading() const {
- return RoleValue() == kHeadingRole;
+ return RoleValue() == ax::mojom::Role::kHeading;
}
bool AXNodeObject::IsHovered() const {
@@ -767,7 +776,7 @@ bool AXNodeObject::IsHovered() const {
}
bool AXNodeObject::IsImage() const {
- return RoleValue() == kImageRole;
+ return RoleValue() == ax::mojom::Role::kImage;
}
bool AXNodeObject::IsImageButton() const {
@@ -776,14 +785,14 @@ bool AXNodeObject::IsImageButton() const {
bool AXNodeObject::IsInputImage() const {
Node* node = this->GetNode();
- if (RoleValue() == kButtonRole && IsHTMLInputElement(node))
+ if (RoleValue() == ax::mojom::Role::kButton && IsHTMLInputElement(node))
return ToHTMLInputElement(*node).type() == InputTypeNames::image;
return false;
}
bool AXNodeObject::IsLink() const {
- return RoleValue() == kLinkRole;
+ return RoleValue() == ax::mojom::Role::kLink;
}
// It is not easily possible to find out if an element is the target of an
@@ -810,24 +819,24 @@ bool AXNodeObject::IsInPageLinkTarget() const {
}
bool AXNodeObject::IsMenu() const {
- return RoleValue() == kMenuRole;
+ return RoleValue() == ax::mojom::Role::kMenu;
}
bool AXNodeObject::IsMenuButton() const {
- return RoleValue() == kMenuButtonRole;
+ return RoleValue() == ax::mojom::Role::kMenuButton;
}
bool AXNodeObject::IsMeter() const {
- return RoleValue() == kMeterRole;
+ return RoleValue() == ax::mojom::Role::kMeter;
}
bool AXNodeObject::IsMultiSelectable() const {
switch (RoleValue()) {
- case kGridRole:
- case kTreeGridRole:
- case kTreeRole:
- case kListBoxRole:
- case kTabListRole: {
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kTabList: {
bool multiselectable = false;
if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable,
multiselectable)) {
@@ -900,15 +909,16 @@ bool AXNodeObject::IsPasswordField() const {
if (!IsHTMLInputElement(node))
return false;
- AccessibilityRole aria_role = AriaRoleAttribute();
- if (aria_role != kTextFieldRole && aria_role != kUnknownRole)
+ ax::mojom::Role aria_role = AriaRoleAttribute();
+ if (aria_role != ax::mojom::Role::kTextField &&
+ aria_role != ax::mojom::Role::kUnknown)
return false;
return ToHTMLInputElement(node)->type() == InputTypeNames::password;
}
bool AXNodeObject::IsProgressIndicator() const {
- return RoleValue() == kProgressIndicatorRole;
+ return RoleValue() == ax::mojom::Role::kProgressIndicator;
}
bool AXNodeObject::IsRichlyEditable() const {
@@ -916,11 +926,11 @@ bool AXNodeObject::IsRichlyEditable() const {
}
bool AXNodeObject::IsSlider() const {
- return RoleValue() == kSliderRole;
+ return RoleValue() == ax::mojom::Role::kSlider;
}
bool AXNodeObject::IsSpinButton() const {
- return RoleValue() == kSpinButtonRole;
+ return RoleValue() == ax::mojom::Role::kSpinButton;
}
bool AXNodeObject::IsNativeSlider() const {
@@ -936,7 +946,7 @@ bool AXNodeObject::IsNativeSpinButton() const {
}
bool AXNodeObject::IsMoveableSplitter() const {
- return RoleValue() == kSplitterRole && CanSetFocusAttribute();
+ return RoleValue() == ax::mojom::Role::kSplitter && CanSetFocusAttribute();
}
bool AXNodeObject::IsClickable() const {
@@ -1007,8 +1017,9 @@ AXRestriction AXNodeObject::Restriction() const {
AXObject* row = ParentObjectUnignored();
if (row->IsTableRowLikeRole()) {
AXObject* table = row->ParentObjectUnignored();
- if (table->IsTableLikeRole() && (table->RoleValue() == kGridRole ||
- table->RoleValue() == kTreeGridRole)) {
+ if (table->IsTableLikeRole() &&
+ (table->RoleValue() == ax::mojom::Role::kGrid ||
+ table->RoleValue() == ax::mojom::Role::kTreeGrid)) {
if (table->Restriction() == kReadOnly)
return kReadOnly;
}
@@ -1040,7 +1051,8 @@ AccessibilityExpanded AXNodeObject::IsExpanded() const {
}
bool AXNodeObject::IsModal() const {
- if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole)
+ if (RoleValue() != ax::mojom::Role::kDialog &&
+ RoleValue() != ax::mojom::Role::kAlertDialog)
return false;
bool modal = false;
@@ -1078,7 +1090,7 @@ int AXNodeObject::HeadingLevel() const {
if (!node)
return 0;
- if (RoleValue() == kHeadingRole) {
+ if (RoleValue() == ax::mojom::Role::kHeading) {
uint32_t level;
if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) {
if (level >= 1 && level <= 9)
@@ -1108,7 +1120,7 @@ int AXNodeObject::HeadingLevel() const {
if (element.HasTagName(h6Tag))
return 6;
- if (RoleValue() == kHeadingRole)
+ if (RoleValue() == ax::mojom::Role::kHeading)
return kDefaultHeadingLevel;
return 0;
@@ -1126,7 +1138,7 @@ unsigned AXNodeObject::HierarchicalLevel() const {
}
// Only tree item will calculate its level through the DOM currently.
- if (RoleValue() != kTreeItemRole)
+ if (RoleValue() != ax::mojom::Role::kTreeItem)
return 0;
// Hierarchy leveling starts at 1, to match the aria-level spec.
@@ -1134,10 +1146,10 @@ unsigned AXNodeObject::HierarchicalLevel() const {
level = 1;
for (AXObject* parent = ParentObject(); parent;
parent = parent->ParentObject()) {
- AccessibilityRole parent_role = parent->RoleValue();
- if (parent_role == kGroupRole)
+ ax::mojom::Role parent_role = parent->RoleValue();
+ if (parent_role == ax::mojom::Role::kGroup)
level++;
- else if (parent_role == kTreeRole)
+ else if (parent_role == ax::mojom::Role::kTree)
break;
}
@@ -1187,14 +1199,23 @@ void AXNodeObject::Markers(Vector<DocumentMarker::MarkerType>& marker_types,
DocumentMarkerController& marker_controller = GetDocument()->Markers();
DocumentMarkerVector markers =
marker_controller.MarkersFor(ToText(*GetNode()));
- for (size_t i = 0; i < markers.size(); ++i) {
- DocumentMarker* marker = markers[i];
- if (MarkerTypeIsUsedForAccessibility(marker->GetType())) {
- marker_types.push_back(marker->GetType());
- marker_ranges.emplace_back(
- AXPosition::CreatePositionInTextObject(*this, marker->StartOffset()),
- AXPosition::CreatePositionInTextObject(*this, marker->EndOffset()));
+ for (DocumentMarker* marker : markers) {
+ if (!MarkerTypeIsUsedForAccessibility(marker->GetType()))
+ continue;
+
+ const Position start_position(*GetNode(), marker->StartOffset());
+ const Position end_position(*GetNode(), marker->EndOffset());
+ if (!start_position.IsValidFor(*GetDocument()) ||
+ !end_position.IsValidFor(*GetDocument())) {
+ continue;
}
+
+ marker_types.push_back(marker->GetType());
+ marker_ranges.emplace_back(
+ AXPosition::FromPosition(start_position, TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveLeft),
+ AXPosition::FromPosition(end_position, TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveRight));
}
}
@@ -1236,27 +1257,27 @@ AccessibilityOrientation AXNodeObject::Orientation() const {
orientation = kAccessibilityOrientationVertical;
switch (RoleValue()) {
- case kListBoxRole:
- case kMenuRole:
- case kScrollBarRole:
- case kTreeRole:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kTree:
if (orientation == kAccessibilityOrientationUndefined)
orientation = kAccessibilityOrientationVertical;
return orientation;
- case kMenuBarRole:
- case kSliderRole:
- case kSplitterRole:
- case kTabListRole:
- case kToolbarRole:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kTabList:
+ case ax::mojom::Role::kToolbar:
if (orientation == kAccessibilityOrientationUndefined)
orientation = kAccessibilityOrientationHorizontal;
return orientation;
- case kComboBoxGroupingRole:
- case kComboBoxMenuButtonRole:
- case kRadioGroupRole:
- case kTreeGridRole:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kTreeGrid:
return orientation;
default:
return AXObject::Orientation();
@@ -1265,15 +1286,14 @@ AccessibilityOrientation AXNodeObject::Orientation() const {
AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const {
AXObjectVector radio_buttons;
- if (!node_ || RoleValue() != kRadioButtonRole)
+ if (!node_ || RoleValue() != ax::mojom::Role::kRadioButton)
return radio_buttons;
if (auto* radio_button = ToHTMLInputElementOrNull(node_)) {
HeapVector<Member<HTMLInputElement>> html_radio_buttons =
FindAllRadioButtonsWithSameName(radio_button);
- for (size_t i = 0; i < html_radio_buttons.size(); ++i) {
- AXObject* ax_radio_button =
- AXObjectCache().GetOrCreate(html_radio_buttons[i]);
+ for (HTMLInputElement* radio_button : html_radio_buttons) {
+ AXObject* ax_radio_button = AXObjectCache().GetOrCreate(radio_button);
if (ax_radio_button)
radio_buttons.push_back(ax_radio_button);
}
@@ -1283,11 +1303,10 @@ AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const {
// If the immediate parent is a radio group, return all its children that are
// radio buttons.
AXObject* parent = ParentObject();
- if (parent && parent->RoleValue() == kRadioGroupRole) {
- for (size_t i = 0; i < parent->Children().size(); ++i) {
- AXObject* child = parent->Children()[i];
+ if (parent && parent->RoleValue() == ax::mojom::Role::kRadioGroup) {
+ for (AXObject* child : parent->Children()) {
DCHECK(child);
- if (child->RoleValue() == kRadioButtonRole &&
+ if (child->RoleValue() == ax::mojom::Role::kRadioButton &&
!child->AccessibilityIsIgnored()) {
radio_buttons.push_back(child);
}
@@ -1358,47 +1377,47 @@ RGBA32 AXNodeObject::ColorValue() const {
return color.Rgb();
}
-AriaCurrentState AXNodeObject::GetAriaCurrentState() const {
+ax::mojom::AriaCurrentState AXNodeObject::GetAriaCurrentState() const {
const AtomicString& attribute_value =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent);
if (attribute_value.IsNull())
- return kAriaCurrentStateUndefined;
+ return ax::mojom::AriaCurrentState::kNone;
if (attribute_value.IsEmpty() ||
EqualIgnoringASCIICase(attribute_value, "false"))
- return kAriaCurrentStateFalse;
+ return ax::mojom::AriaCurrentState::kFalse;
if (EqualIgnoringASCIICase(attribute_value, "true"))
- return kAriaCurrentStateTrue;
+ return ax::mojom::AriaCurrentState::kTrue;
if (EqualIgnoringASCIICase(attribute_value, "page"))
- return kAriaCurrentStatePage;
+ return ax::mojom::AriaCurrentState::kPage;
if (EqualIgnoringASCIICase(attribute_value, "step"))
- return kAriaCurrentStateStep;
+ return ax::mojom::AriaCurrentState::kStep;
if (EqualIgnoringASCIICase(attribute_value, "location"))
- return kAriaCurrentStateLocation;
+ return ax::mojom::AriaCurrentState::kLocation;
if (EqualIgnoringASCIICase(attribute_value, "date"))
- return kAriaCurrentStateDate;
+ return ax::mojom::AriaCurrentState::kDate;
if (EqualIgnoringASCIICase(attribute_value, "time"))
- return kAriaCurrentStateTime;
+ return ax::mojom::AriaCurrentState::kTime;
// An unknown value should return true.
if (!attribute_value.IsEmpty())
- return kAriaCurrentStateTrue;
+ return ax::mojom::AriaCurrentState::kTrue;
return AXObject::GetAriaCurrentState();
}
-InvalidState AXNodeObject::GetInvalidState() const {
+ax::mojom::InvalidState AXNodeObject::GetInvalidState() const {
const AtomicString& attribute_value =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
if (EqualIgnoringASCIICase(attribute_value, "false"))
- return kInvalidStateFalse;
+ return ax::mojom::InvalidState::kFalse;
if (EqualIgnoringASCIICase(attribute_value, "true"))
- return kInvalidStateTrue;
+ return ax::mojom::InvalidState::kTrue;
if (EqualIgnoringASCIICase(attribute_value, "spelling"))
- return kInvalidStateSpelling;
+ return ax::mojom::InvalidState::kSpelling;
if (EqualIgnoringASCIICase(attribute_value, "grammar"))
- return kInvalidStateGrammar;
+ return ax::mojom::InvalidState::kGrammar;
// A yet unknown value.
if (!attribute_value.IsEmpty())
- return kInvalidStateOther;
+ return ax::mojom::InvalidState::kOther;
if (GetNode() && GetNode()->IsElementNode() &&
ToElement(GetNode())->IsFormControlElement()) {
@@ -1406,7 +1425,8 @@ InvalidState AXNodeObject::GetInvalidState() const {
HeapVector<Member<HTMLFormControlElement>> invalid_controls;
bool is_invalid = !element->checkValidity(&invalid_controls,
kCheckValidityDispatchNoEvent);
- return is_invalid ? kInvalidStateTrue : kInvalidStateFalse;
+ return is_invalid ? ax::mojom::InvalidState::kTrue
+ : ax::mojom::InvalidState::kFalse;
}
return AXObject::GetInvalidState();
@@ -1447,14 +1467,15 @@ int AXNodeObject::AutoPosInSet() const {
int pos_in_set = 1;
const AXObject::AXObjectVector siblings = parent->Children();
- AccessibilityRole role = RoleValue();
+ ax::mojom::Role role = RoleValue();
int level = HierarchicalLevel();
int index_in_parent = IndexInParent();
for (int index = index_in_parent - 1; index >= 0; index--) {
const AXObject* sibling = siblings[index];
- AccessibilityRole sibling_role = sibling->RoleValue();
- if (sibling_role == kSplitterRole || sibling_role == kGroupRole)
+ ax::mojom::Role sibling_role = sibling->RoleValue();
+ if (sibling_role == ax::mojom::Role::kSplitter ||
+ sibling_role == ax::mojom::Role::kGroup)
break; // Set stops at a separator or an optgroup.
if (sibling_role != role || sibling->AccessibilityIsIgnored())
continue;
@@ -1483,15 +1504,16 @@ int AXNodeObject::AutoSetSize() const {
int set_size = AutoPosInSet();
auto siblings = parent->Children();
- AccessibilityRole role = RoleValue();
+ ax::mojom::Role role = RoleValue();
int level = HierarchicalLevel();
int index_in_parent = IndexInParent();
int sibling_count = siblings.size();
for (int index = index_in_parent + 1; index < sibling_count; index++) {
const auto sibling = siblings[index];
- AccessibilityRole sibling_role = sibling->RoleValue();
- if (sibling_role == kSplitterRole || sibling_role == kGroupRole)
+ ax::mojom::Role sibling_role = sibling->RoleValue();
+ if (sibling_role == ax::mojom::Role::kSplitter ||
+ sibling_role == ax::mojom::Role::kGroup)
break; // Set stops at a separator or an optgroup.
if (sibling_role != role || sibling->AccessibilityIsIgnored())
continue;
@@ -1510,7 +1532,7 @@ int AXNodeObject::AutoSetSize() const {
}
String AXNodeObject::AriaInvalidValue() const {
- if (GetInvalidState() == kInvalidStateOther)
+ if (GetInvalidState() == ax::mojom::InvalidState::kOther)
return GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid);
return String();
@@ -1546,8 +1568,8 @@ bool AXNodeObject::ValueForRange(float* out_value) const {
// - separator : 50
// - spinbutton : 0
switch (AriaRoleAttribute()) {
- case kScrollBarRole:
- case kSliderRole: {
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSlider: {
float min_value, max_value;
if (MinValueForRange(&min_value) && MaxValueForRange(&max_value)) {
*out_value = (min_value + max_value) / 2.0f;
@@ -1555,11 +1577,11 @@ bool AXNodeObject::ValueForRange(float* out_value) const {
}
FALLTHROUGH;
}
- case kSplitterRole: {
+ case ax::mojom::Role::kSplitter: {
*out_value = 50.0f;
return true;
}
- case kSpinButtonRole: {
+ case ax::mojom::Role::kSpinButton: {
*out_value = 0.0f;
return true;
}
@@ -1590,9 +1612,9 @@ bool AXNodeObject::MaxValueForRange(float* out_value) const {
// In ARIA 1.1, default value of scrollbar, separator and slider
// for aria-valuemax were changed to 100.
switch (AriaRoleAttribute()) {
- case kScrollBarRole:
- case kSplitterRole:
- case kSliderRole: {
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSlider: {
*out_value = 100.0f;
return true;
}
@@ -1623,9 +1645,9 @@ bool AXNodeObject::MinValueForRange(float* out_value) const {
// In ARIA 1.1, default value of scrollbar, separator and slider
// for aria-valuemin were changed to 0.
switch (AriaRoleAttribute()) {
- case kScrollBarRole:
- case kSplitterRole:
- case kSliderRole: {
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSlider: {
*out_value = 0.0f;
return true;
}
@@ -1645,9 +1667,9 @@ bool AXNodeObject::StepValueForRange(float* out_value) const {
}
switch (AriaRoleAttribute()) {
- case kScrollBarRole:
- case kSplitterRole:
- case kSliderRole: {
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSlider: {
*out_value = 0.0f;
return true;
}
@@ -1668,7 +1690,7 @@ String AXNodeObject::StringValue() const {
const HeapVector<Member<HTMLElement>>& list_items =
select_element->GetListItems();
if (selected_index >= 0 &&
- static_cast<size_t>(selected_index) < list_items.size()) {
+ static_cast<wtf_size_t>(selected_index) < list_items.size()) {
const AtomicString& overridden_description =
list_items[selected_index]->FastGetAttribute(aria_labelAttr);
if (!overridden_description.IsNull())
@@ -1701,7 +1723,7 @@ String AXNodeObject::StringValue() const {
return String();
}
-AccessibilityRole AXNodeObject::AriaRoleAttribute() const {
+ax::mojom::Role AXNodeObject::AriaRoleAttribute() const {
return aria_role_;
}
@@ -1737,10 +1759,10 @@ static bool IsInSameNonInlineBlockFlow(LayoutObject* r1, LayoutObject* r2) {
// New AX name calculation.
//
-String AXNodeObject::GetName(AXNameFrom& name_from,
+String AXNodeObject::GetName(ax::mojom::NameFrom& name_from,
AXObjectVector* name_objects) const {
String name = AXObject::GetName(name_from, name_objects);
- if (RoleValue() == kSpinButtonRole && DatetimeAncestor()) {
+ if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) {
// Fields inside a datetime control need to merge the field name with
// the name of the <input> element.
name_objects->clear();
@@ -1755,7 +1777,7 @@ String AXNodeObject::GetName(AXNameFrom& name_from,
String AXNodeObject::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
// If nameSources is non-null, relatedObjects is used in filling it in, so it
@@ -1793,13 +1815,28 @@ String AXNodeObject::TextAlternative(bool recursive,
return StringValue();
}
+ // Step 2E from: http://www.w3.org/TR/accname-aam-1.1
+ // "If the embedded control has role combobox or listbox, return the text
+ // alternative of the chosen option."
+ if (NameFromSelectedOption(recursive)) {
+ StringBuilder accumulated_text;
+ AXObjectVector selected_options;
+ SelectedOptions(selected_options);
+ for (const auto& child : selected_options) {
+ if (accumulated_text.length())
+ accumulated_text.Append(" ");
+ accumulated_text.Append(child->ComputedName());
+ }
+ return accumulated_text.ToString();
+ }
+
// Step 2D from: http://www.w3.org/TR/accname-aam-1.1
text_alternative =
NativeTextAlternative(visited, name_from, related_objects, name_sources,
&found_text_alternative);
const bool has_text_alternative =
!text_alternative.IsEmpty() ||
- name_from == kAXNameFromAttributeExplicitlyEmpty;
+ name_from == ax::mojom::NameFrom::kAttributeExplicitlyEmpty;
if (has_text_alternative && !name_sources)
return text_alternative;
@@ -1807,7 +1844,7 @@ String AXNodeObject::TextAlternative(bool recursive,
if (in_aria_labelled_by_traversal || NameFromContents(recursive)) {
Node* node = GetNode();
if (!IsHTMLSelectElement(node)) { // Avoid option descendant text
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative));
name_sources->back().type = name_from;
@@ -1832,7 +1869,7 @@ String AXNodeObject::TextAlternative(bool recursive,
}
// Step 2H from: http://www.w3.org/TR/accname-aam-1.1
- name_from = kAXNameFromTitle;
+ name_from = ax::mojom::NameFrom::kTitle;
if (name_sources) {
name_sources->push_back(NameSource(found_text_alternative, titleAttr));
name_sources->back().type = name_from;
@@ -1840,6 +1877,7 @@ String AXNodeObject::TextAlternative(bool recursive,
const AtomicString& title = GetAttribute(titleAttr);
if (!title.IsEmpty()) {
text_alternative = title;
+ name_from = ax::mojom::NameFrom::kTitle;
if (name_sources) {
found_text_alternative = true;
name_sources->back().text = text_alternative;
@@ -1848,12 +1886,11 @@ String AXNodeObject::TextAlternative(bool recursive,
}
}
- name_from = kAXNameFromUninitialized;
+ name_from = ax::mojom::NameFrom::kUninitialized;
if (name_sources && found_text_alternative) {
- for (size_t i = 0; i < name_sources->size(); ++i) {
- if (!(*name_sources)[i].text.IsNull() && !(*name_sources)[i].superseded) {
- NameSource& name_source = (*name_sources)[i];
+ for (NameSource& name_source : *name_sources) {
+ if (!name_source.text.IsNull() && !name_source.superseded) {
name_from = name_source.type;
if (!name_source.related_objects.IsEmpty())
*related_objects = name_source.related_objects;
@@ -1865,6 +1902,59 @@ String AXNodeObject::TextAlternative(bool recursive,
return String();
}
+static bool ShouldInsertSpaceBetweenObjectsIfNeeded(
+ AXObject* previous,
+ AXObject* next,
+ ax::mojom::NameFrom last_used_name_from,
+ ax::mojom::NameFrom name_from) {
+ // If we're going between two layoutObjects that are in separate
+ // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if
+ // you have <span>Hello</span><span>World</span>, those are part of the same
+ // LayoutBox so we should return "HelloWorld", but given
+ // <div>Hello</div><div>World</div> the strings are in separate boxes so we
+ // should return "Hello World".
+ if (!IsInSameNonInlineBlockFlow(next->GetLayoutObject(),
+ previous->GetLayoutObject()))
+ return true;
+
+ // Even if it is in the same inline block flow, if we are using a text
+ // alternative such as an ARIA label or HTML title, we should separate
+ // the strings. Doing so is consistent with what is stated in the AccName
+ // spec and with what is done in other user agents.
+ switch (last_used_name_from) {
+ case ax::mojom::NameFrom::kNone:
+ case ax::mojom::NameFrom::kUninitialized:
+ case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
+ case ax::mojom::NameFrom::kContents:
+ break;
+ case ax::mojom::NameFrom::kAttribute:
+ case ax::mojom::NameFrom::kCaption:
+ case ax::mojom::NameFrom::kPlaceholder:
+ case ax::mojom::NameFrom::kRelatedElement:
+ case ax::mojom::NameFrom::kTitle:
+ case ax::mojom::NameFrom::kValue:
+ return true;
+ }
+ switch (name_from) {
+ case ax::mojom::NameFrom::kNone:
+ case ax::mojom::NameFrom::kUninitialized:
+ case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
+ case ax::mojom::NameFrom::kContents:
+ break;
+ case ax::mojom::NameFrom::kAttribute:
+ case ax::mojom::NameFrom::kCaption:
+ case ax::mojom::NameFrom::kPlaceholder:
+ case ax::mojom::NameFrom::kRelatedElement:
+ case ax::mojom::NameFrom::kTitle:
+ case ax::mojom::NameFrom::kValue:
+ return true;
+ }
+
+ // According to the AccName spec, we need to separate controls from text nodes
+ // using a space.
+ return previous->IsControl() || next->IsControl();
+}
+
String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
bool recursive) const {
if (!CanHaveChildren() && recursive)
@@ -1872,6 +1962,7 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
StringBuilder accumulated_text;
AXObject* previous = nullptr;
+ ax::mojom::NameFrom last_used_name_from = ax::mojom::NameFrom::kUninitialized;
AXObjectVector children;
@@ -1893,26 +1984,39 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
if (child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden))
continue;
- // If we're going between two layoutObjects that are in separate
- // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if
- // you have <span>Hello</span><span>World</span>, those are part of the same
- // LayoutBox so we should return "HelloWorld", but given
- // <div>Hello</div><div>World</div> the strings are in separate boxes so we
- // should return "Hello World".
- if (previous && accumulated_text.length() &&
- !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) {
- if (!IsInSameNonInlineBlockFlow(child->GetLayoutObject(),
- previous->GetLayoutObject()))
+ ax::mojom::NameFrom child_name_from = ax::mojom::NameFrom::kUninitialized;
+ String result;
+ if (child->IsPresentational()) {
+ result = child->TextFromDescendants(visited, true);
+ } else {
+ result =
+ RecursiveTextAlternative(*child, false, visited, child_name_from);
+ }
+
+ if (!result.IsEmpty() && previous && accumulated_text.length() &&
+ !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1]) &&
+ !IsHTMLSpace(result[0])) {
+ if (ShouldInsertSpaceBetweenObjectsIfNeeded(
+ previous, child, last_used_name_from, child_name_from)) {
accumulated_text.Append(' ');
+ }
}
- String result;
- if (child->IsPresentational())
- result = child->TextFromDescendants(visited, true);
- else
- result = RecursiveTextAlternative(*child, false, visited);
accumulated_text.Append(result);
+
+ // We keep track of all non-hidden children, even those whose content is
+ // not included, because all rendered children impact whether or not a
+ // space should be inserted between objects. Example: A label which has
+ // a single, nameless input surrounded by CSS-generated content should
+ // have a space separating the before and after content.
previous = child;
+
+ // We only keep track of the source of children whose content is included.
+ // Example: Three spans, the first with an aria-label, the second with no
+ // content, and the third whose name comes from content. There should be a
+ // space between the first and third because of the aria-label in the first.
+ if (!result.IsEmpty())
+ last_used_name_from = child_name_from;
}
return accumulated_text.ToString();
@@ -2134,8 +2238,8 @@ void AXNodeObject::InsertChild(AXObject* child, unsigned index) {
if (child->AccessibilityIsIgnored()) {
const auto& children = child->Children();
- size_t length = children.size();
- for (size_t i = 0; i < length; ++i)
+ wtf_size_t length = children.size();
+ for (wtf_size_t i = 0; i < length; ++i)
children_.insert(index + i, children[i]);
} else {
DCHECK_EQ(child->ParentObject(), this);
@@ -2166,55 +2270,55 @@ bool AXNodeObject::CanHaveChildren() const {
}
switch (native_role_) {
- case kButtonRole:
- case kCheckBoxRole:
- case kImageRole:
- case kListBoxOptionRole:
- case kMenuButtonRole:
- case kMenuListOptionRole:
- case kMenuItemRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kProgressIndicatorRole:
- case kRadioButtonRole:
- case kScrollBarRole:
- // case kSearchBoxRole:
- case kSliderRole:
- case kSplitterRole:
- case kSwitchRole:
- case kTabRole:
- // case kTextFieldRole:
- case kToggleButtonRole:
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kScrollBar:
+ // case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
+ // case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kToggleButton:
return false;
- case kPopUpButtonRole:
+ case ax::mojom::Role::kPopUpButton:
return true;
- case kStaticTextRole:
+ case ax::mojom::Role::kStaticText:
return AXObjectCache().InlineTextBoxAccessibilityEnabled();
default:
break;
}
switch (AriaRoleAttribute()) {
- case kImageRole:
+ case ax::mojom::Role::kImage:
return false;
- case kButtonRole:
- case kCheckBoxRole:
- case kListBoxOptionRole:
- case kMathRole: // role="math" is flat, unlike <math>
- case kMenuButtonRole:
- case kMenuListOptionRole:
- case kMenuItemRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kPopUpButtonRole:
- case kProgressIndicatorRole:
- case kRadioButtonRole:
- case kScrollBarRole:
- case kSliderRole:
- case kSplitterRole:
- case kSwitchRole:
- case kTabRole:
- case kToggleButtonRole: {
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMath: // role="math" is flat, unlike <math>
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kToggleButton: {
// These roles have ChildrenPresentational: true in the ARIA spec.
// We used to remove/prune all descendants of them, but that removed
// useful content if the author didn't follow the spec perfectly, for
@@ -2354,7 +2458,7 @@ bool AXNodeObject::OnNativeFocusAction() {
bool AXNodeObject::OnNativeIncrementAction() {
LocalFrame* frame = GetDocument() ? GetDocument()->GetFrame() : nullptr;
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(frame, UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(frame, UserGestureToken::kNewGesture);
AlterSliderOrSpinButtonValue(true);
return true;
}
@@ -2362,7 +2466,7 @@ bool AXNodeObject::OnNativeIncrementAction() {
bool AXNodeObject::OnNativeDecrementAction() {
LocalFrame* frame = GetDocument() ? GetDocument()->GetFrame() : nullptr;
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(frame, UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(frame, UserGestureToken::kNewGesture);
AlterSliderOrSpinButtonValue(false);
return true;
}
@@ -2408,7 +2512,7 @@ void AXNodeObject::ChildrenChanged() {
if (IsDetached())
return;
- AXObjectCache().PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
+ AXObjectCache().PostNotification(this, ax::mojom::Event::kChildrenChanged);
// Go up the accessibility parent chain, but only if the element already
// exists. This method is called during layout, minimal work should be done.
@@ -2424,16 +2528,16 @@ void AXNodeObject::ChildrenChanged() {
// If this element supports ARIA live regions, then notify the AT of
// changes.
- if (parent->IsLiveRegion())
+ if (parent->IsLiveRegion()) {
AXObjectCache().PostNotification(parent,
- AXObjectCacheImpl::kAXLiveRegionChanged);
+ ax::mojom::Event::kLiveRegionChanged);
+ }
// If this element is an ARIA text box or content editable, post a "value
// changed" notification on it so that it behaves just like a native input
// element or textarea.
if (IsNonNativeTextControl())
- AXObjectCache().PostNotification(parent,
- AXObjectCacheImpl::kAXValueChanged);
+ AXObjectCache().PostNotification(parent, ax::mojom::Event::kValueChanged);
}
}
@@ -2444,17 +2548,47 @@ void AXNodeObject::UpdateChildrenIfNecessary() {
AXObject::UpdateChildrenIfNecessary();
}
+void AXNodeObject::SelectedOptions(AXObjectVector& options) const {
+ if (IsHTMLSelectElement(GetNode())) {
+ HTMLSelectElement* select = ToHTMLSelectElement(GetNode());
+ for (auto* const option : *select->selectedOptions()) {
+ options.push_back(AXObjectCache().GetOrCreate(option));
+ }
+ return;
+ }
+
+ // If the combobox or listbox is a descendant of a label element for another
+ // widget, it may be ignored and Children() won't return all its children.
+ // As a result, we need to use RawFirstChild and RawNextSibling to iterate
+ // over the children in search of the selected option(s).
+
+ if (RoleValue() == ax::mojom::Role::kComboBoxGrouping ||
+ RoleValue() == ax::mojom::Role::kComboBoxMenuButton) {
+ for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
+ if (obj->RoleValue() == ax::mojom::Role::kListBox) {
+ obj->SelectedOptions(options);
+ return;
+ }
+ }
+ }
+
+ for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
+ if (obj->IsSelected() == kSelectedStateTrue)
+ options.push_back(obj);
+ }
+}
+
void AXNodeObject::SelectionChanged() {
// Post the selected text changed event on the first ancestor that's
// focused (to handle form controls, ARIA text boxes and contentEditable),
// or the web area if the selection is just in the document somewhere.
if (IsFocused() || IsWebArea()) {
AXObjectCache().PostNotification(this,
- AXObjectCacheImpl::kAXSelectedTextChanged);
+ ax::mojom::Event::kTextSelectionChanged);
if (GetDocument()) {
AXObject* document_object = AXObjectCache().GetOrCreate(GetDocument());
AXObjectCache().PostNotification(
- document_object, AXObjectCacheImpl::kAXDocumentSelectionChanged);
+ document_object, ax::mojom::Event::kDocumentSelectionChanged);
}
} else {
AXObject::SelectionChanged(); // Calls selectionChanged on parent.
@@ -2472,14 +2606,13 @@ void AXNodeObject::TextChanged() {
continue;
if (parent->IsLiveRegion())
- cache.PostNotification(parent_node,
- AXObjectCacheImpl::kAXLiveRegionChanged);
+ cache.PostNotification(parent_node, ax::mojom::Event::kLiveRegionChanged);
// If this element is an ARIA text box or content editable, post a "value
// changed" notification on it so that it behaves just like a native input
// element or textarea.
if (parent->IsNonNativeTextControl())
- cache.PostNotification(parent_node, AXObjectCacheImpl::kAXValueChanged);
+ cache.PostNotification(parent_node, ax::mojom::Event::kValueChanged);
}
}
@@ -2520,7 +2653,7 @@ void AXNodeObject::ComputeAriaOwnsChildren(
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
String AXNodeObject::NativeTextAlternative(
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources,
bool* found_text_alternative) const {
@@ -2544,7 +2677,7 @@ String AXNodeObject::NativeTextAlternative(
html_element = ToHTMLElement(GetNode());
if (html_element && html_element->IsLabelable()) {
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2578,7 +2711,7 @@ String AXNodeObject::NativeTextAlternative(
source.related_objects = *related_objects;
source.text = text_alternative;
} else {
- return text_alternative;
+ return text_alternative.StripWhiteSpace();
}
} else if (name_sources) {
name_sources->back().invalid = true;
@@ -2589,7 +2722,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.2 input type="button", input type="submit" and input type="reset"
if (input_element && input_element->IsTextButton()) {
// value attribue
- name_from = kAXNameFromValue;
+ name_from = ax::mojom::NameFrom::kValue;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, valueAttr));
name_sources->back().type = name_from;
@@ -2612,7 +2745,7 @@ String AXNodeObject::NativeTextAlternative(
String default_label = input_element->ValueOrDefaultLabel();
if (value.IsNull() && !default_label.IsNull()) {
// default label
- name_from = kAXNameFromContents;
+ name_from = ax::mojom::NameFrom::kContents;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2636,8 +2769,8 @@ String AXNodeObject::NativeTextAlternative(
// alt attr
const AtomicString& alt = input_element->getAttribute(altAttr);
const bool is_empty = alt.IsEmpty() && !alt.IsNull();
- name_from =
- is_empty ? kAXNameFromAttributeExplicitlyEmpty : kAXNameFromAttribute;
+ name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty
+ : ax::mojom::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, altAttr));
name_sources->back().type = name_from;
@@ -2659,7 +2792,7 @@ String AXNodeObject::NativeTextAlternative(
name_sources->push_back(NameSource(*found_text_alternative, valueAttr));
name_sources->back().type = name_from;
}
- name_from = kAXNameFromAttribute;
+ name_from = ax::mojom::NameFrom::kAttribute;
String value = input_element->value();
if (!value.IsNull()) {
text_alternative = value;
@@ -2672,8 +2805,27 @@ String AXNodeObject::NativeTextAlternative(
}
}
+ // title attr
+ if (name_sources) {
+ name_sources->push_back(NameSource(*found_text_alternative, titleAttr));
+ name_sources->back().type = name_from;
+ }
+ name_from = ax::mojom::NameFrom::kTitle;
+ const AtomicString& title = input_element->getAttribute(titleAttr);
+ if (!title.IsNull()) {
+ text_alternative = title;
+ if (name_sources) {
+ NameSource& source = name_sources->back();
+ source.attribute_value = title;
+ source.text = text_alternative;
+ *found_text_alternative = true;
+ } else {
+ return text_alternative;
+ }
+ }
+
// localised default value ("Submit")
- name_from = kAXNameFromValue;
+ name_from = ax::mojom::NameFrom::kValue;
text_alternative = input_element->GetLocale().QueryString(
WebLocalizedString::kSubmitButtonDefaultLabel);
if (name_sources) {
@@ -2691,7 +2843,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.1 Text inputs - step 3 (placeholder attribute)
if (html_element && html_element->IsTextControl()) {
- name_from = kAXNameFromPlaceholder;
+ name_from = ax::mojom::NameFrom::kPlaceholder;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, placeholderAttr));
@@ -2711,9 +2863,11 @@ String AXNodeObject::NativeTextAlternative(
return text_alternative;
}
}
+ }
- // Also check for aria-placeholder.
- name_from = kAXNameFromPlaceholder;
+ // Also check for aria-placeholder.
+ if (IsTextControl()) {
+ name_from = ax::mojom::NameFrom::kPlaceholder;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, aria_placeholderAttr));
@@ -2740,7 +2894,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.7 figure and figcaption Elements
if (GetNode()->HasTagName(figureTag)) {
// figcaption
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2785,8 +2939,8 @@ String AXNodeObject::NativeTextAlternative(
// alt
const AtomicString& alt = GetAttribute(altAttr);
const bool is_empty = alt.IsEmpty() && !alt.IsNull();
- name_from =
- is_empty ? kAXNameFromAttributeExplicitlyEmpty : kAXNameFromAttribute;
+ name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty
+ : ax::mojom::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, altAttr));
name_sources->back().type = name_from;
@@ -2808,7 +2962,7 @@ String AXNodeObject::NativeTextAlternative(
// 5.9 table Element
if (auto* table_element = ToHTMLTableElementOrNull(GetNode())) {
// caption
- name_from = kAXNameFromCaption;
+ name_from = ax::mojom::NameFrom::kCaption;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2839,7 +2993,7 @@ String AXNodeObject::NativeTextAlternative(
}
// summary
- name_from = kAXNameFromAttribute;
+ name_from = ax::mojom::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative, summaryAttr));
name_sources->back().type = name_from;
@@ -2862,7 +3016,7 @@ String AXNodeObject::NativeTextAlternative(
// Per SVG AAM 1.0's modifications to 2D of this algorithm.
if (GetNode()->IsSVGElement()) {
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2897,7 +3051,7 @@ String AXNodeObject::NativeTextAlternative(
// Fieldset / legend.
if (IsHTMLFieldSetElement(GetNode())) {
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2934,7 +3088,7 @@ String AXNodeObject::NativeTextAlternative(
if (IsWebArea()) {
Document* document = this->GetDocument();
if (document) {
- name_from = kAXNameFromAttribute;
+ name_from = ax::mojom::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(
NameSource(found_text_alternative, aria_labelAttr));
@@ -2958,7 +3112,7 @@ String AXNodeObject::NativeTextAlternative(
}
}
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
if (name_sources) {
name_sources->push_back(NameSource(*found_text_alternative));
name_sources->back().type = name_from;
@@ -2992,25 +3146,25 @@ String AXNodeObject::NativeTextAlternative(
return text_alternative;
}
-String AXNodeObject::Description(AXNameFrom name_from,
- AXDescriptionFrom& description_from,
+String AXNodeObject::Description(ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
AXObjectVector* description_objects) const {
AXRelatedObjectVector related_objects;
String result =
Description(name_from, description_from, nullptr, &related_objects);
if (description_objects) {
description_objects->clear();
- for (size_t i = 0; i < related_objects.size(); i++)
- description_objects->push_back(related_objects[i]->object);
+ for (NameSourceRelatedObject* related_object : related_objects)
+ description_objects->push_back(related_object->object);
}
result = CollapseWhitespace(result);
- if (RoleValue() == kSpinButtonRole && DatetimeAncestor()) {
+ if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) {
// Fields inside a datetime control need to merge the field description
// with the description of the <input> element.
const AXObject* datetime_ancestor = DatetimeAncestor();
- AXNameFrom name_from;
+ ax::mojom::NameFrom name_from;
datetime_ancestor->GetName(name_from, nullptr);
description_objects->clear();
String ancestor_description = DatetimeAncestor()->Description(
@@ -3026,8 +3180,8 @@ String AXNodeObject::Description(AXNameFrom name_from,
// Based on
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation
-String AXNodeObject::Description(AXNameFrom name_from,
- AXDescriptionFrom& description_from,
+String AXNodeObject::Description(ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& description_from,
DescriptionSources* description_sources,
AXRelatedObjectVector* related_objects) const {
// If descriptionSources is non-null, relatedObjects is used in filling it in,
@@ -3041,7 +3195,7 @@ String AXNodeObject::Description(AXNameFrom name_from,
String description;
bool found_description = false;
- description_from = kAXDescriptionFromRelatedElement;
+ description_from = ax::mojom::DescriptionFrom::kRelatedElement;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, aria_describedbyAttr));
@@ -3099,9 +3253,9 @@ String AXNodeObject::Description(AXNameFrom name_from,
const HTMLInputElement* input_element = ToHTMLInputElementOrNull(GetNode());
// value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != kAXNameFromValue && input_element &&
+ if (name_from != ax::mojom::NameFrom::kValue && input_element &&
input_element->IsTextButton()) {
- description_from = kAXDescriptionFromAttribute;
+ description_from = ax::mojom::DescriptionFrom::kAttribute;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, valueAttr));
@@ -3122,10 +3276,11 @@ String AXNodeObject::Description(AXNameFrom name_from,
// table caption, 5.9.2 from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != kAXNameFromCaption && IsHTMLTableElement(GetNode())) {
+ if (name_from != ax::mojom::NameFrom::kCaption &&
+ IsHTMLTableElement(GetNode())) {
HTMLTableElement* table_element = ToHTMLTableElement(GetNode());
- description_from = kAXDescriptionFromRelatedElement;
+ description_from = ax::mojom::DescriptionFrom::kRelatedElement;
if (description_sources) {
description_sources->push_back(DescriptionSource(found_description));
description_sources->back().type = description_from;
@@ -3157,8 +3312,9 @@ String AXNodeObject::Description(AXNameFrom name_from,
// summary, 5.6.2 from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != kAXNameFromContents && IsHTMLSummaryElement(GetNode())) {
- description_from = kAXDescriptionFromContents;
+ if (name_from != ax::mojom::NameFrom::kContents &&
+ IsHTMLSummaryElement(GetNode())) {
+ description_from = ax::mojom::DescriptionFrom::kContents;
if (description_sources) {
description_sources->push_back(DescriptionSource(found_description));
description_sources->back().type = description_from;
@@ -3179,8 +3335,8 @@ String AXNodeObject::Description(AXNameFrom name_from,
// title attribute, from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- if (name_from != kAXNameFromTitle) {
- description_from = kAXDescriptionFromAttribute;
+ if (name_from != ax::mojom::NameFrom::kTitle) {
+ description_from = ax::mojom::DescriptionFrom::kAttribute;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, titleAttr));
@@ -3201,7 +3357,7 @@ String AXNodeObject::Description(AXNameFrom name_from,
// aria-help.
// FIXME: this is not part of the official standard, but it's needed because
// the built-in date/time controls use it.
- description_from = kAXDescriptionFromAttribute;
+ description_from = ax::mojom::DescriptionFrom::kAttribute;
if (description_sources) {
description_sources->push_back(
DescriptionSource(found_description, aria_helpAttr));
@@ -3218,13 +3374,11 @@ String AXNodeObject::Description(AXNameFrom name_from,
}
}
- description_from = kAXDescriptionFromUninitialized;
+ description_from = ax::mojom::DescriptionFrom::kUninitialized;
if (found_description) {
- for (size_t i = 0; i < description_sources->size(); ++i) {
- if (!(*description_sources)[i].text.IsNull() &&
- !(*description_sources)[i].superseded) {
- DescriptionSource& description_source = (*description_sources)[i];
+ for (DescriptionSource& description_source : *description_sources) {
+ if (!description_source.text.IsNull() && !description_source.superseded) {
description_from = description_source.type;
if (!description_source.related_objects.IsEmpty())
*related_objects = description_source.related_objects;
@@ -3236,8 +3390,8 @@ String AXNodeObject::Description(AXNameFrom name_from,
return String();
}
-String AXNodeObject::Placeholder(AXNameFrom name_from) const {
- if (name_from == kAXNameFromPlaceholder)
+String AXNodeObject::Placeholder(ax::mojom::NameFrom name_from) const {
+ if (name_from == ax::mojom::NameFrom::kPlaceholder)
return String();
Node* node = GetNode();
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
index a36cf324253..400c2b91aa1 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -55,14 +55,12 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool initialized_ = false;
#endif
// The accessibility role, not taking ARIA into account.
- AccessibilityRole native_role_;
+ ax::mojom::Role native_role_;
bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
const AXObject* InheritsPresentationalRoleFrom() const override;
- AccessibilityRole DetermineAccessibilityRole() override;
- virtual AccessibilityRole NativeAccessibilityRoleIgnoringAria() const;
- String AccessibilityDescriptionForElements(
- HeapVector<Member<Element>>& elements) const;
+ ax::mojom::Role DetermineAccessibilityRole() override;
+ virtual ax::mojom::Role NativeRoleIgnoringAria() const;
void AlterSliderOrSpinButtonValue(bool increase);
AXObject* ActiveDescendant() override;
String AriaAccessibilityDescription() const;
@@ -144,8 +142,8 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
String GetText() const override;
// Properties of interactive elements.
- AriaCurrentState GetAriaCurrentState() const final;
- InvalidState GetInvalidState() const final;
+ ax::mojom::AriaCurrentState GetAriaCurrentState() const final;
+ ax::mojom::InvalidState GetInvalidState() const final;
// Only used when invalidState() returns InvalidStateOther.
String AriaInvalidValue() const final;
String ValueDescription() const override;
@@ -156,24 +154,25 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
String StringValue() const override;
// ARIA attributes.
- AccessibilityRole AriaRoleAttribute() const final;
+ ax::mojom::Role AriaRoleAttribute() const final;
// AX name calculation.
- String GetName(AXNameFrom&, AXObjectVector* name_objects) const override;
+ String GetName(ax::mojom::NameFrom&,
+ AXObjectVector* name_objects) const override;
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
- String Description(AXNameFrom,
- AXDescriptionFrom&,
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
AXObjectVector* description_objects) const override;
- String Description(AXNameFrom,
- AXDescriptionFrom&,
+ String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
DescriptionSources*,
AXRelatedObjectVector*) const override;
- String Placeholder(AXNameFrom) const override;
+ String Placeholder(ax::mojom::NameFrom) const override;
bool NameFromLabelElement() const override;
// Location
@@ -197,6 +196,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool NeedsToUpdateChildren() const override { return children_dirty_; }
void SetNeedsToUpdateChildren() override { children_dirty_ = true; }
void UpdateChildrenIfNecessary() override;
+ void SelectedOptions(AXObjectVector&) const override;
// DOM and Render tree access.
Element* ActionElement() const override;
@@ -235,7 +235,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
String TextFromDescendants(AXObjectSet& visited,
bool recursive) const override;
String NativeTextAlternative(AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*,
bool* found_text_alternative) const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
index dcc25560fb0..25aaa69a578 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -72,372 +72,384 @@ using namespace HTMLNames;
namespace {
-struct AccessibilityRoleHashTraits : HashTraits<AccessibilityRole> {
+struct RoleHashTraits : HashTraits<ax::mojom::Role> {
static const bool kEmptyValueIsZero = true;
- static AccessibilityRole EmptyValue() {
- return AccessibilityRole::kUnknownRole;
- }
+ static ax::mojom::Role EmptyValue() { return ax::mojom::Role::kUnknown; }
};
using ARIARoleMap = HashMap<String,
- AccessibilityRole,
+ ax::mojom::Role,
CaseFoldingHash,
HashTraits<String>,
- AccessibilityRoleHashTraits>;
+ RoleHashTraits>;
struct RoleEntry {
const char* aria_role;
- AccessibilityRole webcore_role;
+ ax::mojom::Role webcore_role;
};
// Mapping of ARIA role name to internal role name.
-const RoleEntry kRoles[] = {{"alert", kAlertRole},
- {"alertdialog", kAlertDialogRole},
- {"application", kApplicationRole},
- {"article", kArticleRole},
- {"banner", kBannerRole},
- {"blockquote", kBlockquoteRole},
- {"button", kButtonRole},
- {"caption", kCaptionRole},
- {"cell", kCellRole},
- {"checkbox", kCheckBoxRole},
- {"columnheader", kColumnHeaderRole},
- {"combobox", kComboBoxGroupingRole},
- {"complementary", kComplementaryRole},
- {"contentinfo", kContentInfoRole},
- {"definition", kDefinitionRole},
- {"dialog", kDialogRole},
- {"directory", kDirectoryRole},
- // -------------------------------------------------
- // DPub Roles:
- // www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
- {"doc-abstract", kDocAbstractRole},
- {"doc-acknowledgments", kDocAcknowledgmentsRole},
- {"doc-afterword", kDocAfterwordRole},
- {"doc-appendix", kDocAppendixRole},
- {"doc-backlink", kDocBackLinkRole},
- {"doc-biblioentry", kDocBiblioEntryRole},
- {"doc-bibliography", kDocBibliographyRole},
- {"doc-biblioref", kDocBiblioRefRole},
- {"doc-chapter", kDocChapterRole},
- {"doc-colophon", kDocColophonRole},
- {"doc-conclusion", kDocConclusionRole},
- {"doc-cover", kDocCoverRole},
- {"doc-credit", kDocCreditRole},
- {"doc-credits", kDocCreditsRole},
- {"doc-dedication", kDocDedicationRole},
- {"doc-endnote", kDocEndnoteRole},
- {"doc-endnotes", kDocEndnotesRole},
- {"doc-epigraph", kDocEpigraphRole},
- {"doc-epilogue", kDocEpilogueRole},
- {"doc-errata", kDocErrataRole},
- {"doc-example", kDocExampleRole},
- {"doc-footnote", kDocFootnoteRole},
- {"doc-foreword", kDocForewordRole},
- {"doc-glossary", kDocGlossaryRole},
- {"doc-glossref", kDocGlossRefRole},
- {"doc-index", kDocIndexRole},
- {"doc-introduction", kDocIntroductionRole},
- {"doc-noteref", kDocNoteRefRole},
- {"doc-notice", kDocNoticeRole},
- {"doc-pagebreak", kDocPageBreakRole},
- {"doc-pagelist", kDocPageListRole},
- {"doc-part", kDocPartRole},
- {"doc-preface", kDocPrefaceRole},
- {"doc-prologue", kDocPrologueRole},
- {"doc-pullquote", kDocPullquoteRole},
- {"doc-qna", kDocQnaRole},
- {"doc-subtitle", kDocSubtitleRole},
- {"doc-tip", kDocTipRole},
- {"doc-toc", kDocTocRole},
- // End DPub roles.
- // -------------------------------------------------
- {"document", kDocumentRole},
- {"feed", kFeedRole},
- {"figure", kFigureRole},
- {"form", kFormRole},
- // -------------------------------------------------
- // ARIA Graphics module roles:
- // https://rawgit.com/w3c/graphics-aam/master/
- {"graphics-document", kGraphicsDocumentRole},
- {"graphics-object", kGraphicsObjectRole},
- {"graphics-symbol", kGraphicsSymbolRole},
- // End ARIA Graphics module roles.
- // -------------------------------------------------
- {"grid", kGridRole},
- {"gridcell", kCellRole},
- {"group", kGroupRole},
- {"heading", kHeadingRole},
- {"img", kImageRole},
- {"link", kLinkRole},
- {"list", kListRole},
- {"listbox", kListBoxRole},
- {"listitem", kListItemRole},
- {"log", kLogRole},
- {"main", kMainRole},
- {"marquee", kMarqueeRole},
- {"math", kMathRole},
- {"menu", kMenuRole},
- {"menubar", kMenuBarRole},
- {"menuitem", kMenuItemRole},
- {"menuitemcheckbox", kMenuItemCheckBoxRole},
- {"menuitemradio", kMenuItemRadioRole},
- {"navigation", kNavigationRole},
- {"none", kNoneRole},
- {"note", kNoteRole},
- {"option", kListBoxOptionRole},
- {"paragraph", kParagraphRole},
- {"presentation", kPresentationalRole},
- {"progressbar", kProgressIndicatorRole},
- {"radio", kRadioButtonRole},
- {"radiogroup", kRadioGroupRole},
- // TODO(accessibility) region should only be mapped
- // if name present. See http://crbug.com/840819.
- {"region", kRegionRole},
- {"row", kRowRole},
- {"rowheader", kRowHeaderRole},
- {"scrollbar", kScrollBarRole},
- {"search", kSearchRole},
- {"searchbox", kSearchBoxRole},
- {"separator", kSplitterRole},
- {"slider", kSliderRole},
- {"spinbutton", kSpinButtonRole},
- {"status", kStatusRole},
- {"switch", kSwitchRole},
- {"tab", kTabRole},
- {"table", kTableRole},
- {"tablist", kTabListRole},
- {"tabpanel", kTabPanelRole},
- {"term", kTermRole},
- {"text", kStaticTextRole},
- {"textbox", kTextFieldRole},
- {"timer", kTimerRole},
- {"toolbar", kToolbarRole},
- {"tooltip", kUserInterfaceTooltipRole},
- {"tree", kTreeRole},
- {"treegrid", kTreeGridRole},
- {"treeitem", kTreeItemRole}};
+const RoleEntry kRoles[] = {
+ {"alert", ax::mojom::Role::kAlert},
+ {"alertdialog", ax::mojom::Role::kAlertDialog},
+ {"application", ax::mojom::Role::kApplication},
+ {"article", ax::mojom::Role::kArticle},
+ {"banner", ax::mojom::Role::kBanner},
+ {"blockquote", ax::mojom::Role::kBlockquote},
+ {"button", ax::mojom::Role::kButton},
+ {"caption", ax::mojom::Role::kCaption},
+ {"cell", ax::mojom::Role::kCell},
+ {"checkbox", ax::mojom::Role::kCheckBox},
+ {"columnheader", ax::mojom::Role::kColumnHeader},
+ {"combobox", ax::mojom::Role::kComboBoxGrouping},
+ {"complementary", ax::mojom::Role::kComplementary},
+ {"contentinfo", ax::mojom::Role::kContentInfo},
+ {"definition", ax::mojom::Role::kDefinition},
+ {"dialog", ax::mojom::Role::kDialog},
+ {"directory", ax::mojom::Role::kDirectory},
+ // -------------------------------------------------
+ // DPub Roles:
+ // www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
+ {"doc-abstract", ax::mojom::Role::kDocAbstract},
+ {"doc-acknowledgments", ax::mojom::Role::kDocAcknowledgments},
+ {"doc-afterword", ax::mojom::Role::kDocAfterword},
+ {"doc-appendix", ax::mojom::Role::kDocAppendix},
+ {"doc-backlink", ax::mojom::Role::kDocBackLink},
+ {"doc-biblioentry", ax::mojom::Role::kDocBiblioEntry},
+ {"doc-bibliography", ax::mojom::Role::kDocBibliography},
+ {"doc-biblioref", ax::mojom::Role::kDocBiblioRef},
+ {"doc-chapter", ax::mojom::Role::kDocChapter},
+ {"doc-colophon", ax::mojom::Role::kDocColophon},
+ {"doc-conclusion", ax::mojom::Role::kDocConclusion},
+ {"doc-cover", ax::mojom::Role::kDocCover},
+ {"doc-credit", ax::mojom::Role::kDocCredit},
+ {"doc-credits", ax::mojom::Role::kDocCredits},
+ {"doc-dedication", ax::mojom::Role::kDocDedication},
+ {"doc-endnote", ax::mojom::Role::kDocEndnote},
+ {"doc-endnotes", ax::mojom::Role::kDocEndnotes},
+ {"doc-epigraph", ax::mojom::Role::kDocEpigraph},
+ {"doc-epilogue", ax::mojom::Role::kDocEpilogue},
+ {"doc-errata", ax::mojom::Role::kDocErrata},
+ {"doc-example", ax::mojom::Role::kDocExample},
+ {"doc-footnote", ax::mojom::Role::kDocFootnote},
+ {"doc-foreword", ax::mojom::Role::kDocForeword},
+ {"doc-glossary", ax::mojom::Role::kDocGlossary},
+ {"doc-glossref", ax::mojom::Role::kDocGlossRef},
+ {"doc-index", ax::mojom::Role::kDocIndex},
+ {"doc-introduction", ax::mojom::Role::kDocIntroduction},
+ {"doc-noteref", ax::mojom::Role::kDocNoteRef},
+ {"doc-notice", ax::mojom::Role::kDocNotice},
+ {"doc-pagebreak", ax::mojom::Role::kDocPageBreak},
+ {"doc-pagelist", ax::mojom::Role::kDocPageList},
+ {"doc-part", ax::mojom::Role::kDocPart},
+ {"doc-preface", ax::mojom::Role::kDocPreface},
+ {"doc-prologue", ax::mojom::Role::kDocPrologue},
+ {"doc-pullquote", ax::mojom::Role::kDocPullquote},
+ {"doc-qna", ax::mojom::Role::kDocQna},
+ {"doc-subtitle", ax::mojom::Role::kDocSubtitle},
+ {"doc-tip", ax::mojom::Role::kDocTip},
+ {"doc-toc", ax::mojom::Role::kDocToc},
+ // End DPub roles.
+ // -------------------------------------------------
+ {"document", ax::mojom::Role::kDocument},
+ {"feed", ax::mojom::Role::kFeed},
+ {"figure", ax::mojom::Role::kFigure},
+ {"form", ax::mojom::Role::kForm},
+ // -------------------------------------------------
+ // ARIA Graphics module roles:
+ // https://rawgit.com/w3c/graphics-aam/master/
+ {"graphics-document", ax::mojom::Role::kGraphicsDocument},
+ {"graphics-object", ax::mojom::Role::kGraphicsObject},
+ {"graphics-symbol", ax::mojom::Role::kGraphicsSymbol},
+ // End ARIA Graphics module roles.
+ // -------------------------------------------------
+ {"grid", ax::mojom::Role::kGrid},
+ {"gridcell", ax::mojom::Role::kCell},
+ {"group", ax::mojom::Role::kGroup},
+ {"heading", ax::mojom::Role::kHeading},
+ {"img", ax::mojom::Role::kImage},
+ {"link", ax::mojom::Role::kLink},
+ {"list", ax::mojom::Role::kList},
+ {"listbox", ax::mojom::Role::kListBox},
+ {"listitem", ax::mojom::Role::kListItem},
+ {"log", ax::mojom::Role::kLog},
+ {"main", ax::mojom::Role::kMain},
+ {"marquee", ax::mojom::Role::kMarquee},
+ {"math", ax::mojom::Role::kMath},
+ {"menu", ax::mojom::Role::kMenu},
+ {"menubar", ax::mojom::Role::kMenuBar},
+ {"menuitem", ax::mojom::Role::kMenuItem},
+ {"menuitemcheckbox", ax::mojom::Role::kMenuItemCheckBox},
+ {"menuitemradio", ax::mojom::Role::kMenuItemRadio},
+ {"navigation", ax::mojom::Role::kNavigation},
+ {"none", ax::mojom::Role::kNone},
+ {"note", ax::mojom::Role::kNote},
+ {"option", ax::mojom::Role::kListBoxOption},
+ {"paragraph", ax::mojom::Role::kParagraph},
+ {"presentation", ax::mojom::Role::kPresentational},
+ {"progressbar", ax::mojom::Role::kProgressIndicator},
+ {"radio", ax::mojom::Role::kRadioButton},
+ {"radiogroup", ax::mojom::Role::kRadioGroup},
+ // TODO(accessibility) region should only be mapped
+ // if name present. See http://crbug.com/840819.
+ {"region", ax::mojom::Role::kRegion},
+ {"row", ax::mojom::Role::kRow},
+ {"rowheader", ax::mojom::Role::kRowHeader},
+ {"scrollbar", ax::mojom::Role::kScrollBar},
+ {"search", ax::mojom::Role::kSearch},
+ {"searchbox", ax::mojom::Role::kSearchBox},
+ {"separator", ax::mojom::Role::kSplitter},
+ {"slider", ax::mojom::Role::kSlider},
+ {"spinbutton", ax::mojom::Role::kSpinButton},
+ {"status", ax::mojom::Role::kStatus},
+ {"switch", ax::mojom::Role::kSwitch},
+ {"tab", ax::mojom::Role::kTab},
+ {"table", ax::mojom::Role::kTable},
+ {"tablist", ax::mojom::Role::kTabList},
+ {"tabpanel", ax::mojom::Role::kTabPanel},
+ {"term", ax::mojom::Role::kTerm},
+ {"text", ax::mojom::Role::kStaticText},
+ {"textbox", ax::mojom::Role::kTextField},
+ {"timer", ax::mojom::Role::kTimer},
+ {"toolbar", ax::mojom::Role::kToolbar},
+ {"tooltip", ax::mojom::Role::kTooltip},
+ {"tree", ax::mojom::Role::kTree},
+ {"treegrid", ax::mojom::Role::kTreeGrid},
+ {"treeitem", ax::mojom::Role::kTreeItem}};
struct InternalRoleEntry {
- AccessibilityRole webcore_role;
+ ax::mojom::Role webcore_role;
const char* internal_role_name;
};
const InternalRoleEntry kInternalRoles[] = {
- {kUnknownRole, "Unknown"},
- {kAbbrRole, "Abbr"},
- {kAlertDialogRole, "AlertDialog"},
- {kAlertRole, "Alert"},
- {kAnchorRole, "Anchor"},
- {kAnnotationRole, "Annotation"},
- {kApplicationRole, "Application"},
- {kArticleRole, "Article"},
- {kAudioRole, "Audio"},
- {kBannerRole, "Banner"},
- {kBlockquoteRole, "Blockquote"},
- {kButtonRole, "Button"},
- {kCanvasRole, "Canvas"},
- {kCaptionRole, "Caption"},
- {kCellRole, "Cell"},
- {kCheckBoxRole, "CheckBox"},
- {kColorWellRole, "ColorWell"},
- {kColumnHeaderRole, "ColumnHeader"},
- {kColumnRole, "Column"},
- {kComboBoxGroupingRole, "ComboBox"},
- {kComboBoxMenuButtonRole, "ComboBox"},
- {kComplementaryRole, "Complementary"},
- {kContentDeletionRole, "ContentDeletion"},
- {kContentInsertionRole, "ContentInsertion"},
- {kContentInfoRole, "ContentInfo"},
- {kDateRole, "Date"},
- {kDateTimeRole, "DateTime"},
- {kDefinitionRole, "Definition"},
- {kDescriptionListDetailRole, "DescriptionListDetail"},
- {kDescriptionListRole, "DescriptionList"},
- {kDescriptionListTermRole, "DescriptionListTerm"},
- {kDetailsRole, "Details"},
- {kDialogRole, "Dialog"},
- {kDirectoryRole, "Directory"},
- {kDisclosureTriangleRole, "DisclosureTriangle"},
+ {ax::mojom::Role::kNone, "None"},
+ {ax::mojom::Role::kAbbr, "Abbr"},
+ {ax::mojom::Role::kAlertDialog, "AlertDialog"},
+ {ax::mojom::Role::kAlert, "Alert"},
+ {ax::mojom::Role::kAnchor, "Anchor"},
+ {ax::mojom::Role::kAnnotation, "Annotation"},
+ {ax::mojom::Role::kApplication, "Application"},
+ {ax::mojom::Role::kArticle, "Article"},
+ {ax::mojom::Role::kAudio, "Audio"},
+ {ax::mojom::Role::kBanner, "Banner"},
+ {ax::mojom::Role::kBlockquote, "Blockquote"},
+ {ax::mojom::Role::kButton, "Button"},
+ {ax::mojom::Role::kCanvas, "Canvas"},
+ {ax::mojom::Role::kCaption, "Caption"},
+ {ax::mojom::Role::kCaret, "Caret"},
+ {ax::mojom::Role::kCell, "Cell"},
+ {ax::mojom::Role::kCheckBox, "CheckBox"},
+ {ax::mojom::Role::kClient, "Client"},
+ {ax::mojom::Role::kColorWell, "ColorWell"},
+ {ax::mojom::Role::kColumnHeader, "ColumnHeader"},
+ {ax::mojom::Role::kColumn, "Column"},
+ {ax::mojom::Role::kComboBoxGrouping, "ComboBox"},
+ {ax::mojom::Role::kComboBoxMenuButton, "ComboBox"},
+ {ax::mojom::Role::kComplementary, "Complementary"},
+ {ax::mojom::Role::kContentDeletion, "ContentDeletion"},
+ {ax::mojom::Role::kContentInsertion, "ContentInsertion"},
+ {ax::mojom::Role::kContentInfo, "ContentInfo"},
+ {ax::mojom::Role::kDate, "Date"},
+ {ax::mojom::Role::kDateTime, "DateTime"},
+ {ax::mojom::Role::kDefinition, "Definition"},
+ {ax::mojom::Role::kDescriptionListDetail, "DescriptionListDetail"},
+ {ax::mojom::Role::kDescriptionList, "DescriptionList"},
+ {ax::mojom::Role::kDescriptionListTerm, "DescriptionListTerm"},
+ {ax::mojom::Role::kDesktop, "Desktop"},
+ {ax::mojom::Role::kDetails, "Details"},
+ {ax::mojom::Role::kDialog, "Dialog"},
+ {ax::mojom::Role::kDirectory, "Directory"},
+ {ax::mojom::Role::kDisclosureTriangle, "DisclosureTriangle"},
// --------------------------------------------------------------
// DPub Roles:
// https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table
- {kDocAbstractRole, "DocAbstract"},
- {kDocAcknowledgmentsRole, "DocAcknowledgments"},
- {kDocAfterwordRole, "DocAfterword"},
- {kDocAppendixRole, "DocAppendix"},
- {kDocBackLinkRole, "DocBackLink"},
- {kDocBiblioEntryRole, "DocBiblioentry"},
- {kDocBibliographyRole, "DocBibliography"},
- {kDocBiblioRefRole, "DocBiblioref"},
- {kDocChapterRole, "DocChapter"},
- {kDocColophonRole, "DocColophon"},
- {kDocConclusionRole, "DocConclusion"},
- {kDocCoverRole, "DocCover"},
- {kDocCreditRole, "DocCredit"},
- {kDocCreditsRole, "DocCredits"},
- {kDocDedicationRole, "DocDedication"},
- {kDocEndnoteRole, "DocEndnote"},
- {kDocEndnotesRole, "DocEndnotes"},
- {kDocEpigraphRole, "DocEpigraph"},
- {kDocEpilogueRole, "DocEpilogue"},
- {kDocErrataRole, "DocErrata"},
- {kDocExampleRole, "DocExample"},
- {kDocFootnoteRole, "DocFootnote"},
- {kDocForewordRole, "DocForeword"},
- {kDocGlossaryRole, "DocGlossary"},
- {kDocGlossRefRole, "DocGlossref"},
- {kDocIndexRole, "DocIndex"},
- {kDocIntroductionRole, "DocIntroduction"},
- {kDocNoteRefRole, "DocNoteref"},
- {kDocNoticeRole, "DocNotice"},
- {kDocPageBreakRole, "DocPagebreak"},
- {kDocPageListRole, "DocPagelist"},
- {kDocPartRole, "DocPart"},
- {kDocPrefaceRole, "DocPreface"},
- {kDocPrologueRole, "DocPrologue"},
- {kDocPullquoteRole, "DocPullquote"},
- {kDocQnaRole, "DocQna"},
- {kDocSubtitleRole, "DocSubtitle"},
- {kDocTipRole, "DocTip"},
- {kDocTocRole, "DocToc"},
+ {ax::mojom::Role::kDocAbstract, "DocAbstract"},
+ {ax::mojom::Role::kDocAcknowledgments, "DocAcknowledgments"},
+ {ax::mojom::Role::kDocAfterword, "DocAfterword"},
+ {ax::mojom::Role::kDocAppendix, "DocAppendix"},
+ {ax::mojom::Role::kDocBackLink, "DocBackLink"},
+ {ax::mojom::Role::kDocBiblioEntry, "DocBiblioentry"},
+ {ax::mojom::Role::kDocBibliography, "DocBibliography"},
+ {ax::mojom::Role::kDocBiblioRef, "DocBiblioref"},
+ {ax::mojom::Role::kDocChapter, "DocChapter"},
+ {ax::mojom::Role::kDocColophon, "DocColophon"},
+ {ax::mojom::Role::kDocConclusion, "DocConclusion"},
+ {ax::mojom::Role::kDocCover, "DocCover"},
+ {ax::mojom::Role::kDocCredit, "DocCredit"},
+ {ax::mojom::Role::kDocCredits, "DocCredits"},
+ {ax::mojom::Role::kDocDedication, "DocDedication"},
+ {ax::mojom::Role::kDocEndnote, "DocEndnote"},
+ {ax::mojom::Role::kDocEndnotes, "DocEndnotes"},
+ {ax::mojom::Role::kDocEpigraph, "DocEpigraph"},
+ {ax::mojom::Role::kDocEpilogue, "DocEpilogue"},
+ {ax::mojom::Role::kDocErrata, "DocErrata"},
+ {ax::mojom::Role::kDocExample, "DocExample"},
+ {ax::mojom::Role::kDocFootnote, "DocFootnote"},
+ {ax::mojom::Role::kDocForeword, "DocForeword"},
+ {ax::mojom::Role::kDocGlossary, "DocGlossary"},
+ {ax::mojom::Role::kDocGlossRef, "DocGlossref"},
+ {ax::mojom::Role::kDocIndex, "DocIndex"},
+ {ax::mojom::Role::kDocIntroduction, "DocIntroduction"},
+ {ax::mojom::Role::kDocNoteRef, "DocNoteref"},
+ {ax::mojom::Role::kDocNotice, "DocNotice"},
+ {ax::mojom::Role::kDocPageBreak, "DocPagebreak"},
+ {ax::mojom::Role::kDocPageList, "DocPagelist"},
+ {ax::mojom::Role::kDocPart, "DocPart"},
+ {ax::mojom::Role::kDocPreface, "DocPreface"},
+ {ax::mojom::Role::kDocPrologue, "DocPrologue"},
+ {ax::mojom::Role::kDocPullquote, "DocPullquote"},
+ {ax::mojom::Role::kDocQna, "DocQna"},
+ {ax::mojom::Role::kDocSubtitle, "DocSubtitle"},
+ {ax::mojom::Role::kDocTip, "DocTip"},
+ {ax::mojom::Role::kDocToc, "DocToc"},
// End DPub roles.
// --------------------------------------------------------------
- {kDocumentRole, "Document"},
- {kEmbeddedObjectRole, "EmbeddedObject"},
- {kFeedRole, "feed"},
- {kFigcaptionRole, "Figcaption"},
- {kFigureRole, "Figure"},
- {kFooterRole, "Footer"},
- {kFormRole, "Form"},
- {kGenericContainerRole, "GenericContainer"},
+ {ax::mojom::Role::kDocument, "Document"},
+ {ax::mojom::Role::kEmbeddedObject, "EmbeddedObject"},
+ {ax::mojom::Role::kFeed, "feed"},
+ {ax::mojom::Role::kFigcaption, "Figcaption"},
+ {ax::mojom::Role::kFigure, "Figure"},
+ {ax::mojom::Role::kFooter, "Footer"},
+ {ax::mojom::Role::kForm, "Form"},
+ {ax::mojom::Role::kGenericContainer, "GenericContainer"},
// --------------------------------------------------------------
// ARIA Graphics module roles:
// https://rawgit.com/w3c/graphics-aam/master/#mapping_role_table
- {kGraphicsDocumentRole, "GraphicsDocument"},
- {kGraphicsObjectRole, "GraphicsObject"},
- {kGraphicsSymbolRole, "GraphicsSymbol"},
+ {ax::mojom::Role::kGraphicsDocument, "GraphicsDocument"},
+ {ax::mojom::Role::kGraphicsObject, "GraphicsObject"},
+ {ax::mojom::Role::kGraphicsSymbol, "GraphicsSymbol"},
// End ARIA Graphics module roles.
// --------------------------------------------------------------
- {kGridRole, "Grid"},
- {kGroupRole, "Group"},
- {kHeadingRole, "Heading"},
- {kIframePresentationalRole, "IframePresentational"},
- {kIframeRole, "Iframe"},
- {kIgnoredRole, "Ignored"},
- {kImageMapRole, "ImageMap"},
- {kImageRole, "Image"},
- {kInlineTextBoxRole, "InlineTextBox"},
- {kInputTimeRole, "InputTime"},
- {kLabelRole, "Label"},
- {kLayoutTableRole, "LayoutTable"},
- {kLayoutTableCellRole, "LayoutCellTable"},
- {kLayoutTableColumnRole, "LayoutColumnTable"},
- {kLayoutTableRowRole, "LayoutRowTable"},
- {kLegendRole, "Legend"},
- {kLinkRole, "Link"},
- {kLineBreakRole, "LineBreak"},
- {kListBoxOptionRole, "ListBoxOption"},
- {kListBoxRole, "ListBox"},
- {kListItemRole, "ListItem"},
- {kListMarkerRole, "ListMarker"},
- {kListRole, "List"},
- {kLogRole, "Log"},
- {kMainRole, "Main"},
- {kMarkRole, "Mark"},
- {kMarqueeRole, "Marquee"},
- {kMathRole, "Math"},
- {kMenuBarRole, "MenuBar"},
- {kMenuButtonRole, "MenuButton"},
- {kMenuItemRole, "MenuItem"},
- {kMenuItemCheckBoxRole, "MenuItemCheckBox"},
- {kMenuItemRadioRole, "MenuItemRadio"},
- {kMenuListOptionRole, "MenuListOption"},
- {kMenuListPopupRole, "MenuListPopup"},
- {kMenuRole, "Menu"},
- {kMeterRole, "Meter"},
- {kNavigationRole, "Navigation"},
- {kNoneRole, "None"},
- {kNoteRole, "Note"},
- {kParagraphRole, "Paragraph"},
- {kPopUpButtonRole, "PopUpButton"},
- {kPreRole, "Pre"},
- {kPresentationalRole, "Presentational"},
- {kProgressIndicatorRole, "ProgressIndicator"},
- {kRadioButtonRole, "RadioButton"},
- {kRadioGroupRole, "RadioGroup"},
- {kRegionRole, "Region"},
- {kRowHeaderRole, "RowHeader"},
- {kRowRole, "Row"},
- {kRubyRole, "Ruby"},
- {kSVGRootRole, "SVGRoot"},
- {kScrollBarRole, "ScrollBar"},
- {kSearchRole, "Search"},
- {kSearchBoxRole, "SearchBox"},
- {kSliderRole, "Slider"},
- {kSliderThumbRole, "SliderThumb"},
- {kSpinButtonRole, "SpinButton"},
- {kSplitterRole, "Splitter"},
- {kStaticTextRole, "StaticText"},
- {kStatusRole, "Status"},
- {kSwitchRole, "Switch"},
- {kTabListRole, "TabList"},
- {kTabPanelRole, "TabPanel"},
- {kTabRole, "Tab"},
- {kTableHeaderContainerRole, "TableHeaderContainer"},
- {kTableRole, "Table"},
- {kTermRole, "Term"},
- {kTextFieldRole, "TextField"},
- {kTextFieldWithComboBoxRole, "ComboBox"},
- {kTimeRole, "Time"},
- {kTimerRole, "Timer"},
- {kToggleButtonRole, "ToggleButton"},
- {kToolbarRole, "Toolbar"},
- {kTreeGridRole, "TreeGrid"},
- {kTreeItemRole, "TreeItem"},
- {kTreeRole, "Tree"},
- {kUserInterfaceTooltipRole, "UserInterfaceTooltip"},
- {kVideoRole, "Video"},
- {kWebAreaRole, "WebArea"}};
-
-static_assert(arraysize(kInternalRoles) == kNumRoles,
+ {ax::mojom::Role::kGrid, "Grid"},
+ {ax::mojom::Role::kGroup, "Group"},
+ {ax::mojom::Role::kHeading, "Heading"},
+ {ax::mojom::Role::kIframePresentational, "IframePresentational"},
+ {ax::mojom::Role::kIframe, "Iframe"},
+ {ax::mojom::Role::kIgnored, "Ignored"},
+ {ax::mojom::Role::kImageMap, "ImageMap"},
+ {ax::mojom::Role::kImage, "Image"},
+ {ax::mojom::Role::kInlineTextBox, "InlineTextBox"},
+ {ax::mojom::Role::kInputTime, "InputTime"},
+ {ax::mojom::Role::kKeyboard, "Keyboard"},
+ {ax::mojom::Role::kLabelText, "Label"},
+ {ax::mojom::Role::kLayoutTable, "LayoutTable"},
+ {ax::mojom::Role::kLayoutTableCell, "LayoutCellTable"},
+ {ax::mojom::Role::kLayoutTableColumn, "LayoutColumnTable"},
+ {ax::mojom::Role::kLayoutTableRow, "LayoutRowTable"},
+ {ax::mojom::Role::kLegend, "Legend"},
+ {ax::mojom::Role::kLink, "Link"},
+ {ax::mojom::Role::kLineBreak, "LineBreak"},
+ {ax::mojom::Role::kListBoxOption, "ListBoxOption"},
+ {ax::mojom::Role::kListBox, "ListBox"},
+ {ax::mojom::Role::kListItem, "ListItem"},
+ {ax::mojom::Role::kListMarker, "ListMarker"},
+ {ax::mojom::Role::kList, "List"},
+ {ax::mojom::Role::kLog, "Log"},
+ {ax::mojom::Role::kMain, "Main"},
+ {ax::mojom::Role::kMark, "Mark"},
+ {ax::mojom::Role::kMarquee, "Marquee"},
+ {ax::mojom::Role::kMath, "Math"},
+ {ax::mojom::Role::kMenuBar, "MenuBar"},
+ {ax::mojom::Role::kMenuButton, "MenuButton"},
+ {ax::mojom::Role::kMenuItem, "MenuItem"},
+ {ax::mojom::Role::kMenuItemCheckBox, "MenuItemCheckBox"},
+ {ax::mojom::Role::kMenuItemRadio, "MenuItemRadio"},
+ {ax::mojom::Role::kMenuListOption, "MenuListOption"},
+ {ax::mojom::Role::kMenuListPopup, "MenuListPopup"},
+ {ax::mojom::Role::kMenu, "Menu"},
+ {ax::mojom::Role::kMeter, "Meter"},
+ {ax::mojom::Role::kNavigation, "Navigation"},
+ {ax::mojom::Role::kNote, "Note"},
+ {ax::mojom::Role::kPane, "Pane"},
+ {ax::mojom::Role::kParagraph, "Paragraph"},
+ {ax::mojom::Role::kPopUpButton, "PopUpButton"},
+ {ax::mojom::Role::kPre, "Pre"},
+ {ax::mojom::Role::kPresentational, "Presentational"},
+ {ax::mojom::Role::kProgressIndicator, "ProgressIndicator"},
+ {ax::mojom::Role::kRadioButton, "RadioButton"},
+ {ax::mojom::Role::kRadioGroup, "RadioGroup"},
+ {ax::mojom::Role::kRegion, "Region"},
+ {ax::mojom::Role::kRootWebArea, "WebArea"},
+ {ax::mojom::Role::kRowHeader, "RowHeader"},
+ {ax::mojom::Role::kRow, "Row"},
+ {ax::mojom::Role::kRuby, "Ruby"},
+ {ax::mojom::Role::kSvgRoot, "SVGRoot"},
+ {ax::mojom::Role::kScrollBar, "ScrollBar"},
+ {ax::mojom::Role::kScrollView, "ScrollView"},
+ {ax::mojom::Role::kSearch, "Search"},
+ {ax::mojom::Role::kSearchBox, "SearchBox"},
+ {ax::mojom::Role::kSlider, "Slider"},
+ {ax::mojom::Role::kSliderThumb, "SliderThumb"},
+ {ax::mojom::Role::kSpinButton, "SpinButton"},
+ {ax::mojom::Role::kSplitter, "Splitter"},
+ {ax::mojom::Role::kStaticText, "StaticText"},
+ {ax::mojom::Role::kStatus, "Status"},
+ {ax::mojom::Role::kSwitch, "Switch"},
+ {ax::mojom::Role::kTabList, "TabList"},
+ {ax::mojom::Role::kTabPanel, "TabPanel"},
+ {ax::mojom::Role::kTab, "Tab"},
+ {ax::mojom::Role::kTableHeaderContainer, "TableHeaderContainer"},
+ {ax::mojom::Role::kTable, "Table"},
+ {ax::mojom::Role::kTerm, "Term"},
+ {ax::mojom::Role::kTextField, "TextField"},
+ {ax::mojom::Role::kTextFieldWithComboBox, "ComboBox"},
+ {ax::mojom::Role::kTime, "Time"},
+ {ax::mojom::Role::kTimer, "Timer"},
+ {ax::mojom::Role::kTitleBar, "TitleBar"},
+ {ax::mojom::Role::kToggleButton, "ToggleButton"},
+ {ax::mojom::Role::kToolbar, "Toolbar"},
+ {ax::mojom::Role::kTreeGrid, "TreeGrid"},
+ {ax::mojom::Role::kTreeItem, "TreeItem"},
+ {ax::mojom::Role::kTree, "Tree"},
+ {ax::mojom::Role::kTooltip, "UserInterfaceTooltip"},
+ {ax::mojom::Role::kUnknown, "Unknown"},
+ {ax::mojom::Role::kVideo, "Video"},
+ {ax::mojom::Role::kWebArea, "WebArea"},
+ {ax::mojom::Role::kWebView, "WebView"},
+ {ax::mojom::Role::kWindow, "Window"}};
+
+static_assert(base::size(kInternalRoles) ==
+ static_cast<size_t>(ax::mojom::Role::kMaxValue) + 1,
"Not all internal roles have an entry in internalRoles array");
// Roles which we need to map in the other direction
-const RoleEntry kReverseRoles[] = {{"button", kToggleButtonRole},
- {"combobox", kPopUpButtonRole},
- {"contentinfo", kFooterRole},
- {"menuitem", kMenuButtonRole},
- {"menuitem", kMenuListOptionRole},
- {"progressbar", kMeterRole},
- {"textbox", kTextFieldRole},
- {"combobox", kComboBoxMenuButtonRole},
- {"combobox", kTextFieldWithComboBoxRole}};
+const RoleEntry kReverseRoles[] = {
+ {"button", ax::mojom::Role::kToggleButton},
+ {"combobox", ax::mojom::Role::kPopUpButton},
+ {"contentinfo", ax::mojom::Role::kFooter},
+ {"menuitem", ax::mojom::Role::kMenuButton},
+ {"menuitem", ax::mojom::Role::kMenuListOption},
+ {"progressbar", ax::mojom::Role::kMeter},
+ {"textbox", ax::mojom::Role::kTextField},
+ {"combobox", ax::mojom::Role::kComboBoxMenuButton},
+ {"combobox", ax::mojom::Role::kTextFieldWithComboBox}};
static ARIARoleMap* CreateARIARoleMap() {
ARIARoleMap* role_map = new ARIARoleMap;
- for (size_t i = 0; i < arraysize(kRoles); ++i)
+ for (size_t i = 0; i < base::size(kRoles); ++i)
role_map->Set(String(kRoles[i].aria_role), kRoles[i].webcore_role);
// Grids "ignore" their non-row children during computation of children.
- role_map->Set(String("rowgroup"), kIgnoredRole);
+ role_map->Set(String("rowgroup"), ax::mojom::Role::kIgnored);
return role_map;
}
static Vector<AtomicString>* CreateRoleNameVector() {
- Vector<AtomicString>* role_name_vector = new Vector<AtomicString>(kNumRoles);
- for (int i = 0; i < kNumRoles; i++)
+ Vector<AtomicString>* role_name_vector =
+ new Vector<AtomicString>(base::size(kInternalRoles));
+ for (size_t i = 0; i < base::size(kInternalRoles); i++)
(*role_name_vector)[i] = g_null_atom;
- for (size_t i = 0; i < arraysize(kRoles); ++i) {
- (*role_name_vector)[kRoles[i].webcore_role] =
+ for (size_t i = 0; i < base::size(kRoles); ++i) {
+ (*role_name_vector)[static_cast<size_t>(kRoles[i].webcore_role)] =
AtomicString(kRoles[i].aria_role);
}
- for (size_t i = 0; i < arraysize(kReverseRoles); ++i) {
- (*role_name_vector)[kReverseRoles[i].webcore_role] =
+ for (size_t i = 0; i < base::size(kReverseRoles); ++i) {
+ (*role_name_vector)[static_cast<size_t>(kReverseRoles[i].webcore_role)] =
AtomicString(kReverseRoles[i].aria_role);
}
@@ -446,9 +458,10 @@ static Vector<AtomicString>* CreateRoleNameVector() {
static Vector<AtomicString>* CreateInternalRoleNameVector() {
Vector<AtomicString>* internal_role_name_vector =
- new Vector<AtomicString>(kNumRoles);
- for (size_t i = 0; i < arraysize(kInternalRoles); i++) {
- (*internal_role_name_vector)[kInternalRoles[i].webcore_role] =
+ new Vector<AtomicString>(base::size(kInternalRoles));
+ for (size_t i = 0; i < base::size(kInternalRoles); i++) {
+ (*internal_role_name_vector)[static_cast<size_t>(
+ kInternalRoles[i].webcore_role)] =
AtomicString(kInternalRoles[i].internal_role_name);
}
@@ -466,8 +479,8 @@ unsigned AXObject::number_of_live_ax_objects_ = 0;
AXObject::AXObject(AXObjectCacheImpl& ax_object_cache)
: id_(0),
have_children_(false),
- role_(kUnknownRole),
- aria_role_(kUnknownRole),
+ role_(ax::mojom::Role::kUnknown),
+ aria_role_(ax::mojom::Role::kUnknown),
last_known_is_ignored_value_(kDefaultBehavior),
explicit_container_id_(0),
parent_(nullptr),
@@ -656,30 +669,31 @@ void AXObject::GetSparseAXAttributes(
}
bool AXObject::IsARIATextControl() const {
- return AriaRoleAttribute() == kTextFieldRole ||
- AriaRoleAttribute() == kSearchBoxRole ||
- AriaRoleAttribute() == kTextFieldWithComboBoxRole;
+ return AriaRoleAttribute() == ax::mojom::Role::kTextField ||
+ AriaRoleAttribute() == ax::mojom::Role::kSearchBox ||
+ AriaRoleAttribute() == ax::mojom::Role::kTextFieldWithComboBox;
}
bool AXObject::IsButton() const {
- AccessibilityRole role = RoleValue();
+ ax::mojom::Role role = RoleValue();
- return role == kButtonRole || role == kPopUpButtonRole ||
- role == kToggleButtonRole;
+ return role == ax::mojom::Role::kButton ||
+ role == ax::mojom::Role::kPopUpButton ||
+ role == ax::mojom::Role::kToggleButton;
}
bool AXObject::IsCheckable() const {
switch (RoleValue()) {
- case kCheckBoxRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kRadioButtonRole:
- case kSwitchRole:
- case kToggleButtonRole:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kToggleButton:
return true;
- case kTreeItemRole:
- case kListBoxOptionRole:
- case kMenuListOptionRole:
+ case ax::mojom::Role::kTreeItem:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuListOption:
return AriaCheckedIsPresent();
default:
return false;
@@ -690,33 +704,34 @@ bool AXObject::IsCheckable() const {
// Because an AXMenuListOption (<option>) can
// have an ARIA role of menuitemcheckbox/menuitemradio
// yet does not inherit from AXNodeObject
-AccessibilityCheckedState AXObject::CheckedState() const {
+ax::mojom::CheckedState AXObject::CheckedState() const {
if (!IsCheckable())
- return kCheckedStateUndefined;
+ return ax::mojom::CheckedState::kNone;
// Try ARIA checked/pressed state
- const AccessibilityRole role = RoleValue();
- const auto prop = role == kToggleButtonRole ? AOMStringProperty::kPressed
- : AOMStringProperty::kChecked;
+ const ax::mojom::Role role = RoleValue();
+ const auto prop = role == ax::mojom::Role::kToggleButton
+ ? AOMStringProperty::kPressed
+ : AOMStringProperty::kChecked;
const AtomicString& checked_attribute = GetAOMPropertyOrARIAAttribute(prop);
if (checked_attribute) {
if (EqualIgnoringASCIICase(checked_attribute, "mixed")) {
// Only checkable role that doesn't support mixed is the switch.
- if (role != kSwitchRole)
- return kCheckedStateMixed;
+ if (role != ax::mojom::Role::kSwitch)
+ return ax::mojom::CheckedState::kMixed;
}
// Anything other than "false" should be treated as "true".
return EqualIgnoringASCIICase(checked_attribute, "false")
- ? kCheckedStateFalse
- : kCheckedStateTrue;
+ ? ax::mojom::CheckedState::kFalse
+ : ax::mojom::CheckedState::kTrue;
}
// Native checked state
- if (role != kToggleButtonRole) {
+ if (role != ax::mojom::Role::kToggleButton) {
const Node* node = this->GetNode();
if (!node)
- return kCheckedStateUndefined;
+ return ax::mojom::CheckedState::kNone;
// Expose native checkbox mixed state as accessibility mixed state. However,
// do not expose native radio mixed state as accessibility mixed state.
@@ -724,15 +739,15 @@ AccessibilityCheckedState AXObject::CheckedState() const {
// both checked and partially checked, but a native mixed native radio
// button sinply means no radio buttons have been checked in the group yet.
if (IsNativeCheckboxInMixedState(node))
- return kCheckedStateMixed;
+ return ax::mojom::CheckedState::kMixed;
if (IsHTMLInputElement(*node) &&
ToHTMLInputElement(*node).ShouldAppearChecked()) {
- return kCheckedStateTrue;
+ return ax::mojom::CheckedState::kTrue;
}
}
- return kCheckedStateFalse;
+ return ax::mojom::CheckedState::kFalse;
}
bool AXObject::IsNativeCheckboxInMixedState(const Node* node) {
@@ -748,34 +763,34 @@ bool AXObject::IsNativeCheckboxInMixedState(const Node* node) {
bool AXObject::IsLandmarkRelated() const {
switch (RoleValue()) {
- case kApplicationRole:
- case kArticleRole:
- case kBannerRole:
- case kComplementaryRole:
- case kContentInfoRole:
- case kDocAcknowledgmentsRole:
- case kDocAfterwordRole:
- case kDocAppendixRole:
- case kDocBibliographyRole:
- case kDocChapterRole:
- case kDocConclusionRole:
- case kDocCreditsRole:
- case kDocEndnotesRole:
- case kDocEpilogueRole:
- case kDocErrataRole:
- case kDocForewordRole:
- case kDocGlossaryRole:
- case kDocIntroductionRole:
- case kDocPartRole:
- case kDocPrefaceRole:
- case kDocPrologueRole:
- case kDocTocRole:
- case kFooterRole:
- case kFormRole:
- case kMainRole:
- case kNavigationRole:
- case kRegionRole:
- case kSearchRole:
+ case ax::mojom::Role::kApplication:
+ case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kBanner:
+ case ax::mojom::Role::kComplementary:
+ case ax::mojom::Role::kContentInfo:
+ case ax::mojom::Role::kDocAcknowledgments:
+ case ax::mojom::Role::kDocAfterword:
+ case ax::mojom::Role::kDocAppendix:
+ case ax::mojom::Role::kDocBibliography:
+ case ax::mojom::Role::kDocChapter:
+ case ax::mojom::Role::kDocConclusion:
+ case ax::mojom::Role::kDocCredits:
+ case ax::mojom::Role::kDocEndnotes:
+ case ax::mojom::Role::kDocEpilogue:
+ case ax::mojom::Role::kDocErrata:
+ case ax::mojom::Role::kDocForeword:
+ case ax::mojom::Role::kDocGlossary:
+ case ax::mojom::Role::kDocIntroduction:
+ case ax::mojom::Role::kDocPart:
+ case ax::mojom::Role::kDocPreface:
+ case ax::mojom::Role::kDocPrologue:
+ case ax::mojom::Role::kDocToc:
+ case ax::mojom::Role::kFooter:
+ case ax::mojom::Role::kForm:
+ case ax::mojom::Role::kMain:
+ case ax::mojom::Role::kNavigation:
+ case ax::mojom::Role::kRegion:
+ case ax::mojom::Role::kSearch:
return true;
default:
return false;
@@ -784,12 +799,12 @@ bool AXObject::IsLandmarkRelated() const {
bool AXObject::IsMenuRelated() const {
switch (RoleValue()) {
- case kMenuRole:
- case kMenuBarRole:
- case kMenuButtonRole:
- case kMenuItemRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
return true;
default:
return false;
@@ -805,11 +820,12 @@ bool AXObject::IsPasswordFieldAndShouldHideValue() const {
}
bool AXObject::IsTextObject() const {
- // Objects with |kLineBreakRole| are HTML <br> elements and are not backed by
- // DOM text nodes. We can't mark them as text objects for that reason.
+ // Objects with |ax::mojom::Role::kLineBreak| are HTML <br> elements and are
+ // not backed by DOM text nodes. We can't mark them as text objects for that
+ // reason.
switch (RoleValue()) {
- case kInlineTextBoxRole:
- case kStaticTextRole:
+ case ax::mojom::Role::kInlineTextBox:
+ case ax::mojom::Role::kStaticText:
return true;
default:
return false;
@@ -820,21 +836,22 @@ bool AXObject::IsClickable() const {
if (IsButton() || IsLink() || IsTextControl())
return true;
- // TODO(dmazzoni): Ensure that kColorWellRole and kSpinButtonRole are
- // correctly handled here via their constituent parts.
+ // TODO(dmazzoni): Ensure that ax::mojom::Role::kColorWell and
+ // ax::mojom::Role::kSpinButton are correctly handled here via their
+ // constituent parts.
switch (RoleValue()) {
- case kCheckBoxRole:
- case kComboBoxMenuButtonRole:
- case kDisclosureTriangleRole:
- case kListBoxRole:
- case kListBoxOptionRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kMenuItemRole:
- case kMenuListOptionRole:
- case kRadioButtonRole:
- case kSwitchRole:
- case kTabRole:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
return true;
default:
return false;
@@ -1099,7 +1116,7 @@ bool AXObject::DispatchEventToAOMEventListeners(Event& event) {
// Bubbling phase.
event.SetEventPhase(Event::kBubblingPhase);
- for (size_t i = 1; i < event_path.size(); i++) {
+ for (wtf_size_t i = 1; i < event_path.size(); i++) {
event.SetCurrentTarget(event_path[i]);
event_path[i]->FireEventListeners(event);
if (event.PropagationStopped())
@@ -1133,10 +1150,10 @@ const AXObject* AXObject::DisabledAncestor() const {
const AXObject* AXObject::DatetimeAncestor(int max_levels_to_check) const {
switch (RoleValue()) {
- case kDateTimeRole:
- case kDateRole:
- case kInputTimeRole:
- case kTimeRole:
+ case ax::mojom::Role::kDateTime:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kInputTime:
+ case ax::mojom::Role::kTime:
return this;
default:
break;
@@ -1185,17 +1202,17 @@ bool AXObject::CanReceiveAccessibilityFocus() const {
bool AXObject::CanSetValueAttribute() const {
switch (RoleValue()) {
- case kColorWellRole:
- case kDateRole:
- case kDateTimeRole:
- case kScrollBarRole:
- case kSliderRole:
- case kSpinButtonRole:
- case kSplitterRole:
- case kTextFieldRole:
- case kTextFieldWithComboBoxRole:
- case kTimeRole:
- case kSearchBoxRole:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kTime:
+ case ax::mojom::Role::kSearchBox:
return Restriction() == kNone;
default:
break;
@@ -1213,7 +1230,7 @@ bool AXObject::CanSetFocusAttribute() const {
// Children of elements with an aria-activedescendant attribute should be
// focusable if they have a (non-presentational) ARIA role.
- if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole &&
+ if (!IsPresentational() && AriaRoleAttribute() != ax::mojom::Role::kUnknown &&
CanBeActiveDescendant()) {
return true;
}
@@ -1228,7 +1245,8 @@ bool AXObject::CanSetFocusAttribute() const {
// don't help when the <option> is canvas fallback, and because
// a common case for aria-owns from a textbox that points to a list
// does not change the hierarchy (textboxes don't support children)
- if (RoleValue() == kListBoxOptionRole || RoleValue() == kMenuListOptionRole)
+ if (RoleValue() == ax::mojom::Role::kListBoxOption ||
+ RoleValue() == ax::mojom::Role::kMenuListOption)
return true;
return node->IsElementNode() && ToElement(node)->SupportsFocus();
@@ -1290,8 +1308,7 @@ bool AXObject::AncestorExposesActiveDescendant() const {
if (!parent)
return false;
- if (parent->SupportsARIAActiveDescendant() &&
- parent->GetAOMPropertyOrARIAAttribute(
+ if (parent->GetAOMPropertyOrARIAAttribute(
AOMRelationProperty::kActiveDescendant)) {
return true;
}
@@ -1300,7 +1317,7 @@ bool AXObject::AncestorExposesActiveDescendant() const {
}
bool AXObject::HasIndirectChildren() const {
- return IsTableCol() || RoleValue() == kTableHeaderContainerRole;
+ return IsTableCol() || RoleValue() == ax::mojom::Role::kTableHeaderContainer;
}
bool AXObject::CanSetSelectedAttribute() const {
@@ -1310,11 +1327,11 @@ bool AXObject::CanSetSelectedAttribute() const {
bool AXObject::IsSubWidget() const {
switch (RoleValue()) {
- case kCellRole:
- case kColumnHeaderRole:
- case kRowHeaderRole:
- case kColumnRole:
- case kRowRole: {
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kRowHeader:
+ case ax::mojom::Role::kColumn:
+ case ax::mojom::Role::kRow: {
// If it has an explicit ARIA role, it's a subwidget.
//
// Reasoning:
@@ -1328,7 +1345,7 @@ bool AXObject::IsSubWidget() const {
// an ARIA 1.1 role of "table", should not be selectable. We may
// need to create separate role enums for grid cells vs table cells
// to implement this.
- if (AriaRoleAttribute() != kUnknownRole)
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
return true;
// Otherwise it's only a subwidget if it's in a grid or treegrid,
@@ -1336,15 +1353,15 @@ bool AXObject::IsSubWidget() const {
AXObject* parent = ParentObjectUnignored();
while (parent && !parent->IsTableLikeRole())
parent = parent->ParentObjectUnignored();
- if (parent && (parent->RoleValue() == kGridRole ||
- parent->RoleValue() == kTreeGridRole))
+ if (parent && (parent->RoleValue() == ax::mojom::Role::kGrid ||
+ parent->RoleValue() == ax::mojom::Role::kTreeGrid))
return true;
return false;
}
- case kListBoxOptionRole:
- case kMenuListOptionRole:
- case kTabRole:
- case kTreeItemRole:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kTreeItem:
return true;
default:
break;
@@ -1354,17 +1371,17 @@ bool AXObject::IsSubWidget() const {
bool AXObject::SupportsARIASetSizeAndPosInSet() const {
switch (RoleValue()) {
- case kArticleRole:
- case kListBoxOptionRole:
- case kListItemRole:
- case kMenuItemRole:
- case kMenuItemRadioRole:
- case kMenuItemCheckBoxRole:
- case kMenuListOptionRole:
- case kRadioButtonRole:
- case kRowRole:
- case kTabRole:
- case kTreeItemRole:
+ case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kListItem:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kRow:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kTreeItem:
return true;
default:
break;
@@ -1387,27 +1404,28 @@ String AXObject::CollapseWhitespace(const String& str) {
}
String AXObject::ComputedName() const {
- AXNameFrom name_from;
+ ax::mojom::NameFrom name_from;
AXObject::AXObjectVector name_objects;
return GetName(name_from, &name_objects);
}
-String AXObject::GetName(AXNameFrom& name_from,
+String AXObject::GetName(ax::mojom::NameFrom& name_from,
AXObject::AXObjectVector* name_objects) const {
HeapHashSet<Member<const AXObject>> visited;
AXRelatedObjectVector related_objects;
String text = TextAlternative(false, false, visited, name_from,
&related_objects, nullptr);
- AccessibilityRole role = RoleValue();
- if (!GetNode() || (!IsHTMLBRElement(GetNode()) && role != kStaticTextRole &&
- role != kInlineTextBoxRole))
+ ax::mojom::Role role = RoleValue();
+ if (!GetNode() ||
+ (!IsHTMLBRElement(GetNode()) && role != ax::mojom::Role::kStaticText &&
+ role != ax::mojom::Role::kInlineTextBox))
text = CollapseWhitespace(text);
if (name_objects) {
name_objects->clear();
- for (size_t i = 0; i < related_objects.size(); i++)
- name_objects->push_back(related_objects[i]->object);
+ for (NameSourceRelatedObject* related_object : related_objects)
+ name_objects->push_back(related_object->object);
}
return text;
@@ -1415,7 +1433,7 @@ String AXObject::GetName(AXNameFrom& name_from,
String AXObject::GetName(NameSources* name_sources) const {
AXObjectSet visited;
- AXNameFrom tmp_name_from;
+ ax::mojom::NameFrom tmp_name_from;
AXRelatedObjectVector tmp_related_objects;
String text = TextAlternative(false, false, visited, tmp_name_from,
&tmp_related_objects, name_sources);
@@ -1426,12 +1444,20 @@ String AXObject::GetName(NameSources* name_sources) const {
String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited) {
+ ax::mojom::NameFrom tmp_name_from;
+ return RecursiveTextAlternative(ax_obj, in_aria_labelled_by_traversal,
+ visited, tmp_name_from);
+}
+
+String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
+ bool in_aria_labelled_by_traversal,
+ AXObjectSet& visited,
+ ax::mojom::NameFrom& name_from) {
if (visited.Contains(&ax_obj) && !in_aria_labelled_by_traversal)
return String();
- AXNameFrom tmp_name_from;
return ax_obj.TextAlternative(true, in_aria_labelled_by_traversal, visited,
- tmp_name_from, nullptr, nullptr);
+ name_from, nullptr, nullptr);
}
bool AXObject::IsHiddenForTextAlternativeCalculation() const {
@@ -1464,7 +1490,7 @@ bool AXObject::IsHiddenForTextAlternativeCalculation() const {
String AXObject::AriaTextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources,
bool* found_text_alternative) const {
@@ -1483,7 +1509,7 @@ String AXObject::AriaTextAlternative(bool recursive,
// Step 2B from: http://www.w3.org/TR/accname-aam-1.1
// If you change this logic, update AXNodeObject::nameFromLabelElement, too.
if (!in_aria_labelled_by_traversal && !already_visited) {
- name_from = kAXNameFromRelatedElement;
+ name_from = ax::mojom::NameFrom::kRelatedElement;
// Check AOM property first.
HeapVector<Member<Element>> elements;
@@ -1560,7 +1586,7 @@ String AXObject::AriaTextAlternative(bool recursive,
// Step 2C from: http://www.w3.org/TR/accname-aam-1.1
// If you change this logic, update AXNodeObject::nameFromLabelElement, too.
- name_from = kAXNameFromAttribute;
+ name_from = ax::mojom::NameFrom::kAttribute;
if (name_sources) {
name_sources->push_back(
NameSource(*found_text_alternative, aria_labelAttr));
@@ -1688,39 +1714,40 @@ void AXObject::TextCharacterOffsets(Vector<int>&) const {}
void AXObject::GetWordBoundaries(Vector<AXRange>&) const {}
-AXDefaultActionVerb AXObject::Action() const {
+ax::mojom::DefaultActionVerb AXObject::Action() const {
Element* action_element = ActionElement();
if (!action_element)
- return AXDefaultActionVerb::kNone;
+ return ax::mojom::DefaultActionVerb::kNone;
// TODO(dmazzoni): Ensure that combo box text field is handled here.
if (IsTextControl())
- return AXDefaultActionVerb::kActivate;
+ return ax::mojom::DefaultActionVerb::kActivate;
if (IsCheckable()) {
- return CheckedState() != kCheckedStateTrue ? AXDefaultActionVerb::kCheck
- : AXDefaultActionVerb::kUncheck;
+ return CheckedState() != ax::mojom::CheckedState::kTrue
+ ? ax::mojom::DefaultActionVerb::kCheck
+ : ax::mojom::DefaultActionVerb::kUncheck;
}
switch (RoleValue()) {
- case kButtonRole:
- case kDisclosureTriangleRole:
- case kToggleButtonRole:
- return AXDefaultActionVerb::kPress;
- case kListBoxOptionRole:
- case kMenuItemRadioRole:
- case kMenuItemRole:
- case kMenuListOptionRole:
- return AXDefaultActionVerb::kSelect;
- case kLinkRole:
- return AXDefaultActionVerb::kJump;
- case kComboBoxMenuButtonRole:
- case kPopUpButtonRole:
- return AXDefaultActionVerb::kOpen;
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kToggleButton:
+ return ax::mojom::DefaultActionVerb::kPress;
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuListOption:
+ return ax::mojom::DefaultActionVerb::kSelect;
+ case ax::mojom::Role::kLink:
+ return ax::mojom::DefaultActionVerb::kJump;
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kPopUpButton:
+ return ax::mojom::DefaultActionVerb::kOpen;
default:
if (action_element == GetNode())
- return AXDefaultActionVerb::kClick;
- return AXDefaultActionVerb::kClickAncestor;
+ return ax::mojom::DefaultActionVerb::kClick;
+ return ax::mojom::DefaultActionVerb::kClickAncestor;
}
}
@@ -1734,105 +1761,129 @@ bool AXObject::AriaCheckedIsPresent() const {
return HasAOMPropertyOrARIAAttribute(AOMStringProperty::kChecked, result);
}
-bool AXObject::SupportsARIAActiveDescendant() const {
- // According to the ARIA Spec, all ARIA composite widgets, ARIA text boxes,
- // ARIA groups and ARIA application should be able to expose an active descendant.
- // Implicitly, <input> and <textarea> elements should also have this ability.
+bool AXObject::SupportsARIAExpanded() const {
switch (RoleValue()) {
- case kComboBoxGroupingRole:
- case kComboBoxMenuButtonRole:
- case kGridRole:
- case kGroupRole:
- case kListBoxRole:
- case kMenuRole:
- case kMenuBarRole:
- case kRadioGroupRole:
- case kRowRole:
- case kSearchBoxRole:
- case kTabListRole:
- case kTextFieldRole:
- case kTextFieldWithComboBoxRole:
- case kToolbarRole:
- case kTreeRole:
- case kTreeGridRole:
- case kApplicationRole:
+ case ax::mojom::Role::kAlertDialog:
+ case ax::mojom::Role::kAlert:
+ case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kBanner:
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kComplementary:
+ case ax::mojom::Role::kContentInfo:
+ case ax::mojom::Role::kDefinition:
+ case ax::mojom::Role::kDialog:
+ case ax::mojom::Role::kDirectory:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kDocument:
+ case ax::mojom::Role::kFeed:
+ case ax::mojom::Role::kFigure:
+ case ax::mojom::Role::kForm:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kGroup:
+ case ax::mojom::Role::kHeading:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kLayoutTable:
+ case ax::mojom::Role::kList:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kListItem:
+ case ax::mojom::Role::kLink:
+ case ax::mojom::Role::kLog:
+ case ax::mojom::Role::kMain:
+ case ax::mojom::Role::kMarquee:
+ case ax::mojom::Role::kMath:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kNavigation:
+ case ax::mojom::Role::kNote:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kRegion:
+ case ax::mojom::Role::kRow:
+ case ax::mojom::Role::kRowHeader:
+ case ax::mojom::Role::kSearch:
+ case ax::mojom::Role::kStatus:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kTable:
+ case ax::mojom::Role::kTabPanel:
+ case ax::mojom::Role::kTerm:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kTimer:
+ case ax::mojom::Role::kToolbar:
+ case ax::mojom::Role::kTooltip:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kTreeItem:
return true;
default:
return false;
}
}
-bool AXObject::SupportsARIAExpanded() const {
- switch (RoleValue()) {
- case kAlertDialogRole:
- case kAlertRole:
- case kArticleRole:
- case kBannerRole:
- case kButtonRole:
- case kCellRole:
- case kColumnHeaderRole:
- case kComboBoxGroupingRole:
- case kComboBoxMenuButtonRole:
- case kComplementaryRole:
- case kContentInfoRole:
- case kDefinitionRole:
- case kDialogRole:
- case kDirectoryRole:
- case kDisclosureTriangleRole:
- case kDocumentRole:
- case kFeedRole:
- case kFigureRole:
- case kFormRole:
- case kGridRole:
- case kGroupRole:
- case kHeadingRole:
- case kImageRole:
- case kLayoutTableRole:
- case kListRole:
- case kListBoxRole:
- case kListBoxOptionRole:
- case kListItemRole:
- case kLinkRole:
- case kLogRole:
- case kMainRole:
- case kMarqueeRole:
- case kMathRole:
- case kMenuRole:
- case kMenuBarRole:
- case kMenuButtonRole:
- case kMenuItemRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kNavigationRole:
- case kNoteRole:
- case kProgressIndicatorRole:
- case kRadioGroupRole:
- case kRegionRole:
- case kRowRole:
- case kRowHeaderRole:
- case kSearchRole:
- case kStatusRole:
- case kTabRole:
- case kTableRole:
- case kTabPanelRole:
- case kTermRole:
- case kTextFieldWithComboBoxRole:
- case kTimerRole:
- case kToolbarRole:
- case kUserInterfaceTooltipRole:
- case kTreeRole:
- case kTreeGridRole:
- case kTreeItemRole:
+bool AXObject::HasGlobalARIAAttribute() const {
+ if (!GetElement())
+ return false;
+
+ AttributeCollection attributes = GetElement()->AttributesWithoutUpdate();
+ for (const Attribute& attr : attributes) {
+ // Attributes cache their uppercase names.
+ auto name = attr.GetName().LocalNameUpper();
+ if (!name.StartsWith("ARIA"))
+ continue;
+ if (name.StartsWith("ARIA-ATOMIC"))
+ return true;
+ if (name.StartsWith("ARIA-BUSY"))
+ return true;
+ if (name.StartsWith("ARIA-CONTROLS"))
+ return true;
+ if (name.StartsWith("ARIA-CURRENT"))
+ return true;
+ if (name.StartsWith("ARIA-DESCRIBEDBY"))
+ return true;
+ if (name.StartsWith("ARIA-DETAILS"))
+ return true;
+ if (name.StartsWith("ARIA-DISABLED"))
+ return true;
+ if (name.StartsWith("ARIA-DROPEFFECT"))
+ return true;
+ if (name.StartsWith("ARIA-ERRORMESSAGE"))
+ return true;
+ if (name.StartsWith("ARIA-FLOWTO"))
+ return true;
+ if (name.StartsWith("ARIA-GRABBED"))
+ return true;
+ if (name.StartsWith("ARIA-HASPOPUP"))
+ return true;
+ if (name.StartsWith("ARIA-HIDDEN"))
+ return true;
+ if (name.StartsWith("ARIA-INVALID"))
+ return true;
+ if (name.StartsWith("ARIA-KEYSHORTCUTS"))
+ return true;
+ if (name.StartsWith("ARIA-LABEL"))
+ return true;
+ if (name.StartsWith("ARIA-LABELEDBY"))
+ return true;
+ if (name.StartsWith("ARIA-LABELLEDBY"))
+ return true;
+ if (name.StartsWith("ARIA-LIVE"))
+ return true;
+ if (name.StartsWith("ARIA-OWNS"))
+ return true;
+ if (name.StartsWith("ARIA-RELEVANT"))
+ return true;
+ if (name.StartsWith("ARIA-ROLEDESCRIPTION"))
return true;
- default:
- return false;
}
-}
-
-bool AXObject::SupportsARIAAttributes() const {
- return IsLiveRegion() || SupportsARIADragging() || SupportsARIADropping() ||
- SupportsARIAFlowTo() || SupportsARIAOwns() ||
- HasAttribute(aria_labelAttr) || HasAttribute(aria_currentAttr);
+ return false;
}
bool AXObject::SupportsRangeValue() const {
@@ -1882,82 +1933,87 @@ AXRestriction AXObject::Restriction() const {
return kNone;
}
-AccessibilityRole AXObject::DetermineAccessibilityRole() {
+ax::mojom::Role AXObject::DetermineAccessibilityRole() {
aria_role_ = DetermineAriaRoleAttribute();
return aria_role_;
}
-AccessibilityRole AXObject::AriaRoleAttribute() const {
+ax::mojom::Role AXObject::AriaRoleAttribute() const {
return aria_role_;
}
-AccessibilityRole AXObject::DetermineAriaRoleAttribute() const {
+ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role.IsNull() || aria_role.IsEmpty())
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
- AccessibilityRole role = AriaRoleToWebCoreRole(aria_role);
+ ax::mojom::Role role = AriaRoleToWebCoreRole(aria_role);
// ARIA states if an item can get focus, it should not be presentational.
- if ((role == kNoneRole || role == kPresentationalRole) &&
- CanSetFocusAttribute())
- return kUnknownRole;
-
- if (role == kButtonRole)
+ // It also states user agents should ignore the presentational role if
+ // the element has global ARIA states and properties.
+ if ((role == ax::mojom::Role::kNone ||
+ role == ax::mojom::Role::kPresentational) &&
+ (CanSetFocusAttribute() || HasGlobalARIAAttribute()))
+ return ax::mojom::Role::kUnknown;
+
+ if (role == ax::mojom::Role::kButton)
role = ButtonRoleType();
role = RemapAriaRoleDueToParent(role);
// Distinguish between different uses of the "combobox" role:
//
- // kComboBoxGroupingRole:
+ // ax::mojom::Role::kComboBoxGrouping:
// <div role="combobox"><input></div>
- // kTextFieldWithComboBoxRole:
+ // ax::mojom::Role::kTextFieldWithComboBox:
// <input role="combobox">
- // kComboBoxMenuButtonRole:
+ // ax::mojom::Role::kComboBoxMenuButton:
// <div tabindex=0 role="combobox">Select</div>
- if (role == kComboBoxGroupingRole) {
+ if (role == ax::mojom::Role::kComboBoxGrouping) {
if (IsNativeTextControl())
- role = kTextFieldWithComboBoxRole;
+ role = ax::mojom::Role::kTextFieldWithComboBox;
else if (GetElement() && GetElement()->SupportsFocus())
- role = kComboBoxMenuButtonRole;
+ role = ax::mojom::Role::kComboBoxMenuButton;
}
- if (role)
+ if (role != ax::mojom::Role::kUnknown)
return role;
- return kUnknownRole;
+ return ax::mojom::Role::kUnknown;
}
-AccessibilityRole AXObject::RemapAriaRoleDueToParent(
- AccessibilityRole role) const {
+ax::mojom::Role AXObject::RemapAriaRoleDueToParent(ax::mojom::Role role) const {
// Some objects change their role based on their parent.
// However, asking for the unignoredParent calls accessibilityIsIgnored(),
// which can trigger a loop. While inside the call stack of creating an
// element, we need to avoid accessibilityIsIgnored().
// https://bugs.webkit.org/show_bug.cgi?id=65174
- if (role != kListBoxOptionRole && role != kMenuItemRole)
+ if (role != ax::mojom::Role::kListBoxOption &&
+ role != ax::mojom::Role::kMenuItem)
return role;
for (AXObject* parent = ParentObject();
parent && !parent->AccessibilityIsIgnored();
parent = parent->ParentObject()) {
- AccessibilityRole parent_aria_role = parent->AriaRoleAttribute();
+ ax::mojom::Role parent_aria_role = parent->AriaRoleAttribute();
// Selects and listboxes both have options as child roles, but they map to
// different roles within WebCore.
- if (role == kListBoxOptionRole && parent_aria_role == kMenuRole)
- return kMenuItemRole;
+ if (role == ax::mojom::Role::kListBoxOption &&
+ parent_aria_role == ax::mojom::Role::kMenu)
+ return ax::mojom::Role::kMenuItem;
// An aria "menuitem" may map to MenuButton or MenuItem depending on its
// parent.
- if (role == kMenuItemRole && parent_aria_role == kGroupRole)
- return kMenuButtonRole;
+ if (role == ax::mojom::Role::kMenuItem &&
+ parent_aria_role == ax::mojom::Role::kGroup)
+ return ax::mojom::Role::kMenuButton;
// If the parent had a different role, then we don't need to continue
// searching up the chain.
- if (parent_aria_role)
+ if (parent_aria_role != ax::mojom::Role::kUnknown)
break;
}
@@ -1981,7 +2037,8 @@ bool AXObject::LiveRegionAtomic() const {
// ARIA roles "alert" and "status" should have an implicit aria-atomic value
// of true.
- return RoleValue() == kAlertRole || RoleValue() == kStatusRole;
+ return RoleValue() == ax::mojom::Role::kAlert ||
+ RoleValue() == ax::mojom::Role::kStatus;
}
const AtomicString& AXObject::ContainerLiveRegionStatus() const {
@@ -2195,18 +2252,18 @@ AXObject* AXObject::ParentObjectUnignored() const {
// sub-widgets
bool AXObject::IsContainerWidget() const {
switch (RoleValue()) {
- case kComboBoxGroupingRole:
- case kComboBoxMenuButtonRole:
- case kGridRole:
- case kListBoxRole:
- case kMenuBarRole:
- case kMenuRole:
- case kRadioGroupRole:
- case kSpinButtonRole:
- case kTabListRole:
- case kToolbarRole:
- case kTreeGridRole:
- case kTreeRole:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kTabList:
+ case ax::mojom::Role::kToolbar:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kTree:
return true;
default:
return false;
@@ -2378,10 +2435,10 @@ void AXObject::SetScrollOffset(const IntPoint& offset) const {
bool AXObject::IsTableLikeRole() const {
switch (RoleValue()) {
- case kLayoutTableRole:
- case kTableRole:
- case kGridRole:
- case kTreeGridRole:
+ case ax::mojom::Role::kLayoutTable:
+ case ax::mojom::Role::kTable:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTreeGrid:
return true;
default:
return false;
@@ -2389,15 +2446,16 @@ bool AXObject::IsTableLikeRole() const {
}
bool AXObject::IsTableRowLikeRole() const {
- return RoleValue() == kRowRole || RoleValue() == kLayoutTableRowRole;
+ return RoleValue() == ax::mojom::Role::kRow ||
+ RoleValue() == ax::mojom::Role::kLayoutTableRow;
}
bool AXObject::IsTableCellLikeRole() const {
switch (RoleValue()) {
- case kLayoutTableCellRole:
- case kCellRole:
- case kColumnHeaderRole:
- case kRowHeaderRole:
+ case ax::mojom::Role::kLayoutTableCell:
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kRowHeader:
return true;
default:
return false;
@@ -2430,7 +2488,7 @@ void AXObject::ColumnHeaders(AXObjectVector& headers) const {
for (const auto& row : TableRowChildren()) {
for (const auto& cell : row->TableCellChildren()) {
- if (cell->RoleValue() == kColumnHeaderRole)
+ if (cell->RoleValue() == ax::mojom::Role::kColumnHeader)
headers.push_back(cell);
}
}
@@ -2442,7 +2500,7 @@ void AXObject::RowHeaders(AXObjectVector& headers) const {
for (const auto& row : TableRowChildren()) {
for (const auto& cell : row->TableCellChildren()) {
- if (cell->RoleValue() == kRowHeaderRole)
+ if (cell->RoleValue() == ax::mojom::Role::kRowHeader)
headers.push_back(cell);
}
}
@@ -2661,7 +2719,7 @@ AXObject::AXObjectVector AXObject::TableRowChildren() const {
for (const auto& child : Children()) {
if (child->IsTableRowLikeRole())
result.push_back(child);
- else if (child->RoleValue() == kGenericContainerRole)
+ else if (child->RoleValue() == ax::mojom::Role::kGenericContainer)
result.AppendVector(child->TableRowChildren());
}
return result;
@@ -2672,7 +2730,7 @@ AXObject::AXObjectVector AXObject::TableCellChildren() const {
for (const auto& child : Children()) {
if (child->IsTableCellLikeRole())
result.push_back(child);
- else if (child->RoleValue() == kGenericContainerRole)
+ else if (child->RoleValue() == ax::mojom::Role::kGenericContainer)
result.AppendVector(child->TableCellChildren());
}
return result;
@@ -2681,7 +2739,7 @@ AXObject::AXObjectVector AXObject::TableCellChildren() const {
const AXObject* AXObject::TableRowParent() const {
const AXObject* row = ParentObjectUnignored();
while (row && !row->IsTableRowLikeRole() &&
- row->RoleValue() == kGenericContainerRole)
+ row->RoleValue() == ax::mojom::Role::kGenericContainer)
row = row->ParentObjectUnignored();
return row;
}
@@ -2689,7 +2747,7 @@ const AXObject* AXObject::TableRowParent() const {
const AXObject* AXObject::TableParent() const {
const AXObject* table = ParentObjectUnignored();
while (table && !table->IsTableLikeRole() &&
- table->RoleValue() == kGenericContainerRole)
+ table->RoleValue() == ax::mojom::Role::kGenericContainer)
table = table->ParentObjectUnignored();
return table;
}
@@ -2856,8 +2914,8 @@ bool AXObject::OnNativeClickAction() {
return false;
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(document->GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(document->GetFrame(),
+ UserGestureToken::kNewGesture);
Element* element = GetElement();
if (!element && GetNode())
@@ -2933,12 +2991,10 @@ bool AXObject::RequestShowContextMenuAction() {
}
bool AXObject::InternalClearAccessibilityFocusAction() {
- // TODO(mlamouri): implement
return false;
}
bool AXObject::InternalSetAccessibilityFocusAction() {
- // TODO(mlamouri): implement
return false;
}
@@ -2955,7 +3011,7 @@ bool AXObject::OnNativeScrollToMakeVisibleAction() const {
kProgrammaticScroll, false, kScrollBehaviorAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- AXObjectCacheImpl::kAXLocationChanged);
+ ax::mojom::Event::kLocationChanged);
return true;
}
@@ -2981,7 +3037,7 @@ bool AXObject::OnNativeScrollToMakeVisibleWithSubFocusAction(
kProgrammaticScroll, false, kScrollBehaviorAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- AXObjectCacheImpl::kAXLocationChanged);
+ ax::mojom::Event::kLocationChanged);
return true;
}
@@ -3000,7 +3056,7 @@ bool AXObject::OnNativeScrollToGlobalPointAction(
kProgrammaticScroll, false, kScrollBehaviorAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
- AXObjectCacheImpl::kAXLocationChanged);
+ ax::mojom::Event::kLocationChanged);
return true;
}
@@ -3089,35 +3145,52 @@ int AXObject::LineForPosition(const VisiblePosition& position) const {
}
// static
-bool AXObject::IsARIAControl(AccessibilityRole aria_role) {
- return IsARIAInput(aria_role) || aria_role == kButtonRole ||
- aria_role == kComboBoxMenuButtonRole || aria_role == kSliderRole;
+bool AXObject::IsARIAControl(ax::mojom::Role aria_role) {
+ return IsARIAInput(aria_role) || aria_role == ax::mojom::Role::kButton ||
+ aria_role == ax::mojom::Role::kComboBoxMenuButton ||
+ aria_role == ax::mojom::Role::kSlider;
}
// static
-bool AXObject::IsARIAInput(AccessibilityRole aria_role) {
- return aria_role == kRadioButtonRole || aria_role == kCheckBoxRole ||
- aria_role == kTextFieldRole || aria_role == kSwitchRole ||
- aria_role == kSearchBoxRole || aria_role == kTextFieldWithComboBoxRole;
+bool AXObject::IsARIAInput(ax::mojom::Role aria_role) {
+ return aria_role == ax::mojom::Role::kRadioButton ||
+ aria_role == ax::mojom::Role::kCheckBox ||
+ aria_role == ax::mojom::Role::kTextField ||
+ aria_role == ax::mojom::Role::kSwitch ||
+ aria_role == ax::mojom::Role::kSearchBox ||
+ aria_role == ax::mojom::Role::kTextFieldWithComboBox;
}
-AccessibilityRole AXObject::AriaRoleToWebCoreRole(const String& value) {
+ax::mojom::Role AXObject::AriaRoleToWebCoreRole(const String& value) {
DCHECK(!value.IsEmpty());
static const ARIARoleMap* role_map = CreateARIARoleMap();
Vector<String> role_vector;
value.Split(' ', role_vector);
- AccessibilityRole role = kUnknownRole;
+ ax::mojom::Role role = ax::mojom::Role::kUnknown;
for (const auto& child : role_vector) {
role = role_map->at(child);
- if (role)
+ if (role != ax::mojom::Role::kUnknown)
return role;
}
return role;
}
+bool AXObject::NameFromSelectedOption(bool recursive) const {
+ switch (RoleValue()) {
+ // Step 2E from: http://www.w3.org/TR/accname-aam-1.1
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kPopUpButton:
+ return recursive;
+ default:
+ return false;
+ }
+}
+
bool AXObject::NameFromContents(bool recursive) const {
// ARIA 1.1, section 5.2.7.5.
bool result = false;
@@ -3125,191 +3198,200 @@ bool AXObject::NameFromContents(bool recursive) const {
switch (RoleValue()) {
// ----- NameFrom: contents -------------------------
// Get their own name from contents, or contribute to ancestors
- case kAnchorRole:
- case kButtonRole:
- case kCellRole:
- case kCheckBoxRole:
- case kColumnHeaderRole:
- case kComboBoxMenuButtonRole:
- case kDocBackLinkRole:
- case kDocBiblioRefRole:
- case kDocNoteRefRole:
- case kDocGlossRefRole:
- case kDisclosureTriangleRole:
- case kHeadingRole:
- case kLayoutTableCellRole:
- case kLineBreakRole:
- case kLinkRole:
- case kListBoxOptionRole:
- case kMenuButtonRole:
- case kMenuItemRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kMenuListOptionRole:
- case kPopUpButtonRole:
- case kRadioButtonRole:
- case kRowHeaderRole:
- case kStaticTextRole:
- case kSwitchRole:
- case kTabRole:
- case kToggleButtonRole:
- case kTreeItemRole:
- case kUserInterfaceTooltipRole:
+ case ax::mojom::Role::kAnchor:
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kDocBackLink:
+ case ax::mojom::Role::kDocBiblioRef:
+ case ax::mojom::Role::kDocNoteRef:
+ case ax::mojom::Role::kDocGlossRef:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kHeading:
+ case ax::mojom::Role::kLayoutTableCell:
+ case ax::mojom::Role::kLineBreak:
+ case ax::mojom::Role::kLink:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kRowHeader:
+ case ax::mojom::Role::kStaticText:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kToggleButton:
+ case ax::mojom::Role::kTreeItem:
+ case ax::mojom::Role::kTooltip:
result = true;
break;
// ----- No name from contents -------------------------
// These never have or contribute a name from contents, as they are
// containers for many subobjects. Superset of nameFrom:author ARIA roles.
- case kAlertRole:
- case kAlertDialogRole:
- case kApplicationRole:
- case kAudioRole:
- case kArticleRole:
- case kBannerRole:
- case kBlockquoteRole:
- case kColorWellRole:
- case kColumnRole:
- case kComboBoxGroupingRole:
- case kComplementaryRole:
- case kContentInfoRole:
- case kDateRole:
- case kDateTimeRole:
- case kDefinitionRole:
- case kDialogRole:
- case kDirectoryRole:
- case kDocCoverRole:
- case kDocBiblioEntryRole:
- case kDocEndnoteRole:
- case kDocFootnoteRole:
- case kDocPageBreakRole:
- case kDocAbstractRole:
- case kDocAcknowledgmentsRole:
- case kDocAfterwordRole:
- case kDocAppendixRole:
- case kDocBibliographyRole:
- case kDocChapterRole:
- case kDocColophonRole:
- case kDocConclusionRole:
- case kDocCreditRole:
- case kDocCreditsRole:
- case kDocDedicationRole:
- case kDocEndnotesRole:
- case kDocEpigraphRole:
- case kDocEpilogueRole:
- case kDocErrataRole:
- case kDocExampleRole:
- case kDocForewordRole:
- case kDocGlossaryRole:
- case kDocIndexRole:
- case kDocIntroductionRole:
- case kDocNoticeRole:
- case kDocPageListRole:
- case kDocPartRole:
- case kDocPrefaceRole:
- case kDocPrologueRole:
- case kDocPullquoteRole:
- case kDocQnaRole:
- case kDocSubtitleRole:
- case kDocTipRole:
- case kDocTocRole:
- case kDocumentRole:
- case kEmbeddedObjectRole:
- case kFeedRole:
- case kFigureRole:
- case kFormRole:
- case kGraphicsDocumentRole:
- case kGraphicsObjectRole:
- case kGraphicsSymbolRole:
- case kGridRole:
- case kGroupRole:
- case kIframePresentationalRole:
- case kIframeRole:
- case kImageRole:
- case kInputTimeRole:
- case kListBoxRole:
- case kLogRole:
- case kMainRole:
- case kMarqueeRole:
- case kMathRole:
- case kMenuListPopupRole:
- case kMenuRole:
- case kMenuBarRole:
- case kMeterRole:
- case kNavigationRole:
- case kNoteRole:
- case kProgressIndicatorRole:
- case kRadioGroupRole:
- case kScrollBarRole:
- case kSearchRole:
- case kSearchBoxRole:
- case kSplitterRole:
- case kSliderRole:
- case kSpinButtonRole:
- case kStatusRole:
- case kSliderThumbRole:
- case kSVGRootRole:
- case kTableRole:
- case kTableHeaderContainerRole:
- case kTabListRole:
- case kTabPanelRole:
- case kTermRole:
- case kTextFieldRole:
- case kTextFieldWithComboBoxRole:
- case kTimeRole:
- case kTimerRole:
- case kToolbarRole:
- case kTreeRole:
- case kTreeGridRole:
- case kVideoRole:
- case kWebAreaRole:
+ case ax::mojom::Role::kAlert:
+ case ax::mojom::Role::kAlertDialog:
+ case ax::mojom::Role::kApplication:
+ case ax::mojom::Role::kAudio:
+ case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kBanner:
+ case ax::mojom::Role::kBlockquote:
+ case ax::mojom::Role::kCaret:
+ case ax::mojom::Role::kClient:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kColumn:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComplementary:
+ case ax::mojom::Role::kContentInfo:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
+ case ax::mojom::Role::kDefinition:
+ case ax::mojom::Role::kDesktop:
+ case ax::mojom::Role::kDialog:
+ case ax::mojom::Role::kDirectory:
+ case ax::mojom::Role::kDocCover:
+ case ax::mojom::Role::kDocBiblioEntry:
+ case ax::mojom::Role::kDocEndnote:
+ case ax::mojom::Role::kDocFootnote:
+ case ax::mojom::Role::kDocPageBreak:
+ case ax::mojom::Role::kDocAbstract:
+ case ax::mojom::Role::kDocAcknowledgments:
+ case ax::mojom::Role::kDocAfterword:
+ case ax::mojom::Role::kDocAppendix:
+ case ax::mojom::Role::kDocBibliography:
+ case ax::mojom::Role::kDocChapter:
+ case ax::mojom::Role::kDocColophon:
+ case ax::mojom::Role::kDocConclusion:
+ case ax::mojom::Role::kDocCredit:
+ case ax::mojom::Role::kDocCredits:
+ case ax::mojom::Role::kDocDedication:
+ case ax::mojom::Role::kDocEndnotes:
+ case ax::mojom::Role::kDocEpigraph:
+ case ax::mojom::Role::kDocEpilogue:
+ case ax::mojom::Role::kDocErrata:
+ case ax::mojom::Role::kDocExample:
+ case ax::mojom::Role::kDocForeword:
+ case ax::mojom::Role::kDocGlossary:
+ case ax::mojom::Role::kDocIndex:
+ case ax::mojom::Role::kDocIntroduction:
+ case ax::mojom::Role::kDocNotice:
+ case ax::mojom::Role::kDocPageList:
+ case ax::mojom::Role::kDocPart:
+ case ax::mojom::Role::kDocPreface:
+ case ax::mojom::Role::kDocPrologue:
+ case ax::mojom::Role::kDocPullquote:
+ case ax::mojom::Role::kDocQna:
+ case ax::mojom::Role::kDocSubtitle:
+ case ax::mojom::Role::kDocTip:
+ case ax::mojom::Role::kDocToc:
+ case ax::mojom::Role::kDocument:
+ case ax::mojom::Role::kEmbeddedObject:
+ case ax::mojom::Role::kFeed:
+ case ax::mojom::Role::kFigure:
+ case ax::mojom::Role::kForm:
+ case ax::mojom::Role::kGraphicsDocument:
+ case ax::mojom::Role::kGraphicsObject:
+ case ax::mojom::Role::kGraphicsSymbol:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kGroup:
+ case ax::mojom::Role::kIframePresentational:
+ case ax::mojom::Role::kIframe:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kInputTime:
+ case ax::mojom::Role::kKeyboard:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kLog:
+ case ax::mojom::Role::kMain:
+ case ax::mojom::Role::kMarquee:
+ case ax::mojom::Role::kMath:
+ case ax::mojom::Role::kMenuListPopup:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMeter:
+ case ax::mojom::Role::kNavigation:
+ case ax::mojom::Role::kNote:
+ case ax::mojom::Role::kPane:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kScrollView:
+ case ax::mojom::Role::kSearch:
+ case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kStatus:
+ case ax::mojom::Role::kSliderThumb:
+ case ax::mojom::Role::kSvgRoot:
+ case ax::mojom::Role::kTable:
+ case ax::mojom::Role::kTableHeaderContainer:
+ case ax::mojom::Role::kTabList:
+ case ax::mojom::Role::kTabPanel:
+ case ax::mojom::Role::kTerm:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kTitleBar:
+ case ax::mojom::Role::kTime:
+ case ax::mojom::Role::kTimer:
+ case ax::mojom::Role::kToolbar:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kVideo:
+ case ax::mojom::Role::kWebArea:
+ case ax::mojom::Role::kWebView:
result = false;
break;
// ----- Conditional: contribute to ancestor only, unless focusable -------
// Some objects can contribute their contents to ancestor names, but
// only have their own name if they are focusable
- case kAbbrRole:
- case kAnnotationRole:
- case kCanvasRole:
- case kCaptionRole:
- case kContentDeletionRole:
- case kContentInsertionRole:
- case kDescriptionListDetailRole:
- case kDescriptionListRole:
- case kDescriptionListTermRole:
- case kDetailsRole:
- case kFigcaptionRole:
- case kFooterRole:
- case kGenericContainerRole:
- case kIgnoredRole:
- case kImageMapRole:
- case kInlineTextBoxRole:
- case kLabelRole:
- case kLayoutTableRole:
- case kLayoutTableColumnRole:
- case kLayoutTableRowRole:
- case kLegendRole:
- case kListRole:
- case kListItemRole:
- case kListMarkerRole:
- case kMarkRole:
- case kNoneRole:
- case kParagraphRole:
- case kPreRole:
- case kPresentationalRole:
- case kRegionRole:
+ case ax::mojom::Role::kAbbr:
+ case ax::mojom::Role::kAnnotation:
+ case ax::mojom::Role::kCanvas:
+ case ax::mojom::Role::kCaption:
+ case ax::mojom::Role::kContentDeletion:
+ case ax::mojom::Role::kContentInsertion:
+ case ax::mojom::Role::kDescriptionListDetail:
+ case ax::mojom::Role::kDescriptionList:
+ case ax::mojom::Role::kDescriptionListTerm:
+ case ax::mojom::Role::kDetails:
+ case ax::mojom::Role::kFigcaption:
+ case ax::mojom::Role::kFooter:
+ case ax::mojom::Role::kGenericContainer:
+ case ax::mojom::Role::kIgnored:
+ case ax::mojom::Role::kImageMap:
+ case ax::mojom::Role::kInlineTextBox:
+ case ax::mojom::Role::kLabelText:
+ case ax::mojom::Role::kLayoutTable:
+ case ax::mojom::Role::kLayoutTableColumn:
+ case ax::mojom::Role::kLayoutTableRow:
+ case ax::mojom::Role::kLegend:
+ case ax::mojom::Role::kList:
+ case ax::mojom::Role::kListItem:
+ case ax::mojom::Role::kListMarker:
+ case ax::mojom::Role::kMark:
+ case ax::mojom::Role::kNone:
+ case ax::mojom::Role::kParagraph:
+ case ax::mojom::Role::kPre:
+ case ax::mojom::Role::kPresentational:
+ case ax::mojom::Role::kRegion:
// Spec says we should always expose the name on rows,
// but for performance reasons we only do it
// if the row might receive focus
- case kRowRole:
- case kRubyRole:
+ case ax::mojom::Role::kRow:
+ case ax::mojom::Role::kRuby:
result = recursive || (CanReceiveAccessibilityFocus() && !IsEditable());
break;
- case kUnknownRole:
- case kNumRoles:
- LOG(ERROR) << "kUnknownRole for " << GetNode();
+ case ax::mojom::Role::kUnknown:
+ case ax::mojom::Role::kMaxValue:
+ LOG(ERROR) << "ax::mojom::Role::kUnknown for " << GetNode();
NOTREACHED();
break;
}
@@ -3319,31 +3401,31 @@ bool AXObject::NameFromContents(bool recursive) const {
bool AXObject::SupportsARIAReadOnly() const {
switch (RoleValue()) {
- case kCellRole:
- case kCheckBoxRole:
- case kColorWellRole:
- case kColumnHeaderRole:
- case kComboBoxGroupingRole:
- case kComboBoxMenuButtonRole:
- case kDateRole:
- case kDateTimeRole:
- case kGridRole:
- case kInputTimeRole:
- case kListBoxRole:
- case kMenuButtonRole:
- case kMenuItemCheckBoxRole:
- case kMenuItemRadioRole:
- case kPopUpButtonRole:
- case kRadioGroupRole:
- case kRowHeaderRole:
- case kSearchBoxRole:
- case kSliderRole:
- case kSpinButtonRole:
- case kSwitchRole:
- case kTextFieldRole:
- case kTextFieldWithComboBoxRole:
- case kToggleButtonRole:
- case kTreeGridRole:
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kInputTime:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kRowHeader:
+ case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kToggleButton:
+ case ax::mojom::Role::kTreeGrid:
return true;
default:
break;
@@ -3351,32 +3433,32 @@ bool AXObject::SupportsARIAReadOnly() const {
return false;
}
-AccessibilityRole AXObject::ButtonRoleType() const {
+ax::mojom::Role AXObject::ButtonRoleType() const {
// If aria-pressed is present, then it should be exposed as a toggle button.
// http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed
if (AriaPressedIsPresent())
- return kToggleButtonRole;
- if (HasPopup())
- return kPopUpButtonRole;
+ return ax::mojom::Role::kToggleButton;
+ if (HasPopup() != ax::mojom::HasPopup::kFalse)
+ return ax::mojom::Role::kPopUpButton;
// We don't contemplate RadioButtonRole, as it depends on the input
// type.
- return kButtonRole;
+ return ax::mojom::Role::kButton;
}
// static
-const AtomicString& AXObject::RoleName(AccessibilityRole role) {
+const AtomicString& AXObject::RoleName(ax::mojom::Role role) {
static const Vector<AtomicString>* role_name_vector = CreateRoleNameVector();
- return role_name_vector->at(role);
+ return role_name_vector->at(static_cast<size_t>(role));
}
// static
-const AtomicString& AXObject::InternalRoleName(AccessibilityRole role) {
+const AtomicString& AXObject::InternalRoleName(ax::mojom::Role role) {
static const Vector<AtomicString>* internal_role_name_vector =
CreateInternalRoleNameVector();
- return internal_role_name_vector->at(role);
+ return internal_role_name_vector->at(static_cast<size_t>(role));
}
// static
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
index 12df974b31e..34a1c79bd49 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -8,12 +8,14 @@
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * 2.
+ * Redistributiothird_party/blink/renderer/modules/exported/web_ax_object.ccns
+ * in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. 3. Neither the name of Apple
+ * Computer, Inc. ("Apple") nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -45,8 +47,10 @@
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "ui/accessibility/ax_enums.mojom-blink.h"
class SkMatrix44;
@@ -80,7 +84,7 @@ class AXSparseAttributeClient {
};
class IgnoredReason {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
AXIgnoredReason reason;
@@ -111,13 +115,13 @@ class NameSourceRelatedObject
typedef HeapVector<Member<NameSourceRelatedObject>> AXRelatedObjectVector;
class NameSource {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
String text;
bool superseded = false;
bool invalid = false;
- AXNameFrom type = kAXNameFromUninitialized;
+ ax::mojom::NameFrom type = ax::mojom::NameFrom::kUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
@@ -133,13 +137,13 @@ class NameSource {
};
class DescriptionSource {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
String text;
bool superseded = false;
bool invalid = false;
- AXDescriptionFrom type = kAXDescriptionFromUninitialized;
+ ax::mojom::DescriptionFrom type = ax::mojom::DescriptionFrom::kUninitialized;
const QualifiedName& attribute;
AtomicString attribute_value;
AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized;
@@ -167,7 +171,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
typedef HeapVector<Member<AXObject>> AXObjectVector;
struct AXSelection {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
// The deepest descendant in which the range starts.
// (nullptr means the current object.)
Persistent<AXObject> anchor_object;
@@ -456,15 +460,17 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual bool IsAXSVGRoot() const { return false; }
// Check object role or purpose.
- virtual AccessibilityRole RoleValue() const { return role_; }
+ virtual ax::mojom::Role RoleValue() const { return role_; }
bool IsARIATextControl() const;
virtual bool IsARIARow() const { return false; }
virtual bool IsAnchor() const { return false; }
bool IsButton() const;
- bool IsCanvas() const { return RoleValue() == kCanvasRole; }
- bool IsCheckbox() const { return RoleValue() == kCheckBoxRole; }
+ bool IsCanvas() const { return RoleValue() == ax::mojom::Role::kCanvas; }
+ bool IsCheckbox() const { return RoleValue() == ax::mojom::Role::kCheckBox; }
bool IsCheckboxOrRadio() const { return IsCheckbox() || IsRadioButton(); }
- bool IsColorWell() const { return RoleValue() == kColorWellRole; }
+ bool IsColorWell() const {
+ return RoleValue() == ax::mojom::Role::kColorWell;
+ }
virtual bool IsControl() const { return false; }
virtual bool IsEmbeddedObject() const { return false; }
virtual bool IsFieldset() const { return false; }
@@ -494,31 +500,40 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual bool IsPasswordField() const { return false; }
virtual bool IsPasswordFieldAndShouldHideValue() const;
bool IsPresentational() const {
- return RoleValue() == kNoneRole || RoleValue() == kPresentationalRole;
+ return RoleValue() == ax::mojom::Role::kNone ||
+ RoleValue() == ax::mojom::Role::kPresentational;
}
virtual bool IsProgressIndicator() const { return false; }
- bool IsRadioButton() const { return RoleValue() == kRadioButtonRole; }
+ bool IsRadioButton() const {
+ return RoleValue() == ax::mojom::Role::kRadioButton;
+ }
bool IsRange() const {
- return RoleValue() == kProgressIndicatorRole ||
- RoleValue() == kScrollBarRole || RoleValue() == kSliderRole ||
- RoleValue() == kSpinButtonRole || IsMoveableSplitter();
+ return RoleValue() == ax::mojom::Role::kProgressIndicator ||
+ RoleValue() == ax::mojom::Role::kScrollBar ||
+ RoleValue() == ax::mojom::Role::kSlider ||
+ RoleValue() == ax::mojom::Role::kSpinButton || IsMoveableSplitter();
+ }
+ bool IsScrollbar() const {
+ return RoleValue() == ax::mojom::Role::kScrollBar;
}
- bool IsScrollbar() const { return RoleValue() == kScrollBarRole; }
virtual bool IsSlider() const { return false; }
virtual bool IsNativeSlider() const { return false; }
virtual bool IsMoveableSplitter() const { return false; }
- virtual bool IsSpinButton() const { return RoleValue() == kSpinButtonRole; }
- bool IsTabItem() const { return RoleValue() == kTabRole; }
+ virtual bool IsSpinButton() const {
+ return RoleValue() == ax::mojom::Role::kSpinButton;
+ }
+ bool IsTabItem() const { return RoleValue() == ax::mojom::Role::kTab; }
virtual bool IsTextControl() const { return false; }
bool IsTextObject() const;
- bool IsTree() const { return RoleValue() == kTreeRole; }
+ bool IsTree() const { return RoleValue() == ax::mojom::Role::kTree; }
virtual bool IsVirtualObject() const { return false; }
- bool IsWebArea() const { return RoleValue() == kWebAreaRole; }
+ bool IsWebArea() const {
+ return RoleValue() == ax::mojom::Role::kRootWebArea;
+ }
// Check object state.
virtual bool IsAutofillAvailable() { return false; }
virtual bool IsClickable() const;
- virtual bool IsCollapsed() const { return false; }
virtual AccessibilityExpanded IsExpanded() const {
return kExpandedUndefined;
}
@@ -577,7 +592,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
// Retrieves the accessible name of the object, an enum indicating where the
// name was derived from, and a list of objects that were used to derive the
// name, if any.
- virtual String GetName(AXNameFrom&, AXObjectVector* name_objects) const;
+ virtual String GetName(ax::mojom::NameFrom&,
+ AXObjectVector* name_objects) const;
typedef HeapVector<NameSource> NameSources;
// Retrieves the accessible name of the object and a list of all potential
@@ -589,16 +605,16 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
// accessible description of the object, which is secondary to |name|, an enum
// indicating where the description was derived from, and a list of objects
// that were used to derive the description, if any.
- virtual String Description(AXNameFrom,
- AXDescriptionFrom&,
+ virtual String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
AXObjectVector* description_objects) const {
return String();
}
// Same as above, but returns a list of all potential sources for the
// description, indicating which were used.
- virtual String Description(AXNameFrom,
- AXDescriptionFrom&,
+ virtual String Description(ax::mojom::NameFrom,
+ ax::mojom::DescriptionFrom&,
DescriptionSources*,
AXRelatedObjectVector*) const {
return String();
@@ -607,14 +623,14 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
// Takes the result of nameFrom and descriptionFrom from calling |name| and
// |description|, above, and retrieves the placeholder of the object, if
// present and if it wasn't already exposed by one of the two functions above.
- virtual String Placeholder(AXNameFrom) const { return String(); }
+ virtual String Placeholder(ax::mojom::NameFrom) const { return String(); }
// Internal functions used by name and description, above.
typedef HeapHashSet<Member<const AXObject>> AXObjectSet;
virtual String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
return String();
@@ -662,10 +678,12 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual AXObject* InPageLinkTarget() const { return nullptr; }
virtual AccessibilityOrientation Orientation() const;
virtual String GetText() const { return String(); }
- virtual AccessibilityTextDirection GetTextDirection() const {
- return kAccessibilityTextDirectionLTR;
+ virtual ax::mojom::TextDirection GetTextDirection() const {
+ return ax::mojom::TextDirection::kLtr;
+ }
+ virtual ax::mojom::TextPosition GetTextPosition() const {
+ return ax::mojom::TextPosition::kNone;
}
- virtual AXTextPosition GetTextPosition() const { return kAXTextPositionNone; }
virtual int TextLength() const { return 0; }
virtual TextStyle GetTextStyle() const { return kTextStyleNone; }
virtual AXObjectVector RadioButtonsInGroup() const {
@@ -694,13 +712,13 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual void GetWordBoundaries(Vector<AXRange>&) const;
// Properties of interactive elements.
- AXDefaultActionVerb Action() const;
- AccessibilityCheckedState CheckedState() const;
- virtual AriaCurrentState GetAriaCurrentState() const {
- return kAriaCurrentStateUndefined;
+ ax::mojom::DefaultActionVerb Action() const;
+ ax::mojom::CheckedState CheckedState() const;
+ virtual ax::mojom::AriaCurrentState GetAriaCurrentState() const {
+ return ax::mojom::AriaCurrentState::kNone;
}
- virtual InvalidState GetInvalidState() const {
- return kInvalidStateUndefined;
+ virtual ax::mojom::InvalidState GetInvalidState() const {
+ return ax::mojom::InvalidState::kNone;
}
// Only used when invalidState() returns InvalidStateOther.
virtual String AriaInvalidValue() const { return String(); }
@@ -713,14 +731,16 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual AXRestriction Restriction() const;
// ARIA attributes.
- virtual AccessibilityRole DetermineAccessibilityRole();
- AccessibilityRole DetermineAriaRoleAttribute() const;
- virtual AccessibilityRole AriaRoleAttribute() const;
+ virtual ax::mojom::Role DetermineAccessibilityRole();
+ ax::mojom::Role DetermineAriaRoleAttribute() const;
+ virtual ax::mojom::Role AriaRoleAttribute() const;
virtual AXObject* ActiveDescendant() { return nullptr; }
virtual String AriaAutoComplete() const { return String(); }
virtual void AriaOwnsElements(AXObjectVector& owns) const {}
virtual void AriaDescribedbyElements(AXObjectVector&) const {}
- virtual AXHasPopup HasPopup() const { return kAXHasPopupFalse; }
+ virtual ax::mojom::HasPopup HasPopup() const {
+ return ax::mojom::HasPopup::kFalse;
+ }
virtual bool IsEditable() const { return false; }
bool IsEditableRoot() const;
virtual bool ComputeIsEditableRoot() const { return false; }
@@ -728,8 +748,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual bool IsRichlyEditable() const { return false; }
bool AriaCheckedIsPresent() const;
bool AriaPressedIsPresent() const;
- bool SupportsARIAActiveDescendant() const;
- bool SupportsARIAAttributes() const;
+ bool HasGlobalARIAAttribute() const;
bool SupportsARIAExpanded() const;
virtual bool SupportsARIADragging() const { return false; }
virtual bool SupportsARIADropping() const { return false; }
@@ -836,6 +855,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual void DetachFromParent() { parent_ = nullptr; }
virtual AXObject* ScrollBar(AccessibilityOrientation) { return nullptr; }
virtual void AddAccessibleNodeChildren();
+ virtual void SelectedOptions(AXObjectVector&) const {}
// Properties of the object's owning document or page.
virtual double EstimatedLoadingProgress() const { return 0; }
@@ -891,8 +911,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual unsigned AriaRowIndex() const;
virtual int AriaColumnCount() const;
virtual int AriaRowCount() const;
- virtual SortDirection GetSortDirection() const {
- return kSortDirectionUndefined;
+ virtual ax::mojom::SortDirection GetSortDirection() const {
+ return ax::mojom::SortDirection::kNone;
}
// For a row or column.
@@ -965,13 +985,13 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
virtual void LineBreaks(Vector<int>&) const {}
// Static helper functions.
- static bool IsARIAControl(AccessibilityRole);
- static bool IsARIAInput(AccessibilityRole);
+ static bool IsARIAControl(ax::mojom::Role);
+ static bool IsARIAInput(ax::mojom::Role);
// Is this a widget that requires container widget.
bool IsSubWidget() const;
- static AccessibilityRole AriaRoleToWebCoreRole(const String&);
- static const AtomicString& RoleName(AccessibilityRole);
- static const AtomicString& InternalRoleName(AccessibilityRole);
+ static ax::mojom::Role AriaRoleToWebCoreRole(const String&);
+ static const AtomicString& RoleName(ax::mojom::Role);
+ static const AtomicString& InternalRoleName(ax::mojom::Role);
static void AccessibleNodeListToElementVector(const AccessibleNodeList&,
HeapVector<Member<Element>>&);
@@ -988,8 +1008,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
AXID id_;
AXObjectVector children_;
mutable bool have_children_;
- AccessibilityRole role_;
- AccessibilityRole aria_role_;
+ ax::mojom::Role role_;
+ ax::mojom::Role aria_role_;
mutable AXObjectInclusion last_known_is_ignored_value_;
LayoutRect explicit_element_rect_;
AXID explicit_container_id_;
@@ -999,11 +1019,15 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
static String RecursiveTextAlternative(const AXObject&,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited);
+ static String RecursiveTextAlternative(const AXObject&,
+ bool in_aria_labelled_by_traversal,
+ AXObjectSet& visited,
+ ax::mojom::NameFrom& name_from);
bool IsHiddenForTextAlternativeCalculation() const;
String AriaTextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*,
bool* found_text_alternative) const;
@@ -1027,8 +1051,9 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
bool CanReceiveAccessibilityFocus() const;
bool NameFromContents(bool recursive) const;
+ bool NameFromSelectedOption(bool recursive) const;
- AccessibilityRole ButtonRoleType() const;
+ ax::mojom::Role ButtonRoleType() const;
virtual LayoutObject* LayoutObjectForRelativeBounds() const {
return nullptr;
@@ -1079,7 +1104,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
static bool IsNativeCheckboxInMixedState(const Node*);
static bool IncludesARIAWidgetRole(const String&);
static bool HasInteractiveARIAAttribute(const Element&);
- AccessibilityRole RemapAriaRoleDueToParent(AccessibilityRole) const;
+ ax::mojom::Role RemapAriaRoleDueToParent(ax::mojom::Role) const;
unsigned ComputeAriaColumnIndex() const;
unsigned ComputeAriaRowIndex() const;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 009e2d02edb..1f7c45f7ce8 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -456,14 +456,14 @@ AXObject* AXObjectCacheImpl::GetOrCreate(
return new_obj;
}
-AXObject* AXObjectCacheImpl::GetOrCreate(AccessibilityRole role) {
+AXObject* AXObjectCacheImpl::GetOrCreate(ax::mojom::Role role) {
AXObject* obj = nullptr;
switch (role) {
- case kSliderThumbRole:
+ case ax::mojom::Role::kSliderThumb:
obj = AXSliderThumb::Create(*this);
break;
- case kMenuListPopupRole:
+ case ax::mojom::Role::kMenuListPopup:
obj = AXMenuListPopup::Create(*this);
break;
default:
@@ -677,11 +677,11 @@ void AXObjectCacheImpl::TextChanged(AXObject* obj,
if (node_for_relation_update)
relation_cache_->UpdateRelatedTree(node_for_relation_update);
- PostNotification(obj, AXObjectCacheImpl::kAXTextChanged);
+ PostNotification(obj, ax::mojom::Event::kTextChanged);
}
void AXObjectCacheImpl::DocumentTitleChanged() {
- PostNotification(Root(), AXObjectCacheImpl::kAXDocumentTitleChanged);
+ PostNotification(Root(), ax::mojom::Event::kDocumentTitleChanged);
}
void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) {
@@ -707,20 +707,49 @@ void AXObjectCacheImpl::DidInsertChildrenOfNode(Node* node) {
}
void AXObjectCacheImpl::ChildrenChanged(Node* node) {
+ if (!node)
+ return;
+
+ if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
+ nodes_changed_during_layout_.push_back(node);
+ return;
+ }
ChildrenChanged(Get(node), node);
}
void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) {
- if (layout_object) {
- AXObject* object = Get(layout_object);
- ChildrenChanged(object, layout_object->GetNode());
+ if (!layout_object)
+ return;
+ Node* node = layout_object->GetNode();
+ LayoutObject* parent = layout_object->Parent();
+ while (!node && parent) {
+ node = layout_object->GetNode();
+ parent = parent->Parent();
}
+
+ if (!node)
+ return;
+
+ if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) {
+ nodes_changed_during_layout_.push_back(node);
+ return;
+ }
+
+ AXObject* object = Get(layout_object);
+ ChildrenChanged(object, layout_object->GetNode());
}
void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) {
+ if (!accessible_node)
+ return;
+ Element* element = accessible_node->element();
+ if (element &&
+ element->GetDocument().NeedsLayoutTreeUpdateForNode(*element)) {
+ nodes_changed_during_layout_.push_back(element);
+ return;
+ }
AXObject* object = Get(accessible_node);
- if (object)
- ChildrenChanged(object, object->GetNode());
+ ChildrenChanged(object, object ? object->GetNode() : nullptr);
}
void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
@@ -733,6 +762,21 @@ void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
}
}
+void AXObjectCacheImpl::ProcessUpdatesAfterLayout(Document& document) {
+ if (document.Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
+ return;
+
+ HeapVector<Member<Node>> remaining_nodes;
+ for (auto node : nodes_changed_during_layout_) {
+ if (node->GetDocument() != document) {
+ remaining_nodes.push_back(node);
+ continue;
+ }
+ ChildrenChanged(Get(node), node);
+ }
+ nodes_changed_during_layout_.swap(remaining_nodes);
+}
+
void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) {
notification_post_timer_.Stop();
@@ -757,10 +801,11 @@ void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) {
}
#endif
- AXNotification notification = notifications_to_post_[i].second;
+ ax::mojom::Event notification = notifications_to_post_[i].second;
PostPlatformNotification(obj, notification);
- if (notification == kAXChildrenChanged && obj->ParentObjectIfExists() &&
+ if (notification == ax::mojom::Event::kChildrenChanged &&
+ obj->ParentObjectIfExists() &&
obj->LastKnownIsIgnoredValue() != obj->AccessibilityIsIgnored())
ChildrenChanged(obj->ParentObject());
}
@@ -769,21 +814,21 @@ void AXObjectCacheImpl::NotificationPostTimerFired(TimerBase*) {
}
void AXObjectCacheImpl::PostNotification(LayoutObject* layout_object,
- AXNotification notification) {
+ ax::mojom::Event notification) {
if (!layout_object)
return;
PostNotification(Get(layout_object), notification);
}
void AXObjectCacheImpl::PostNotification(Node* node,
- AXNotification notification) {
+ ax::mojom::Event notification) {
if (!node)
return;
PostNotification(Get(node), notification);
}
void AXObjectCacheImpl::PostNotification(AXObject* object,
- AXNotification notification) {
+ ax::mojom::Event notification) {
if (!object)
return;
@@ -809,16 +854,16 @@ void AXObjectCacheImpl::UpdateAriaOwns(
}
void AXObjectCacheImpl::CheckedStateChanged(Node* node) {
- PostNotification(node, AXObjectCacheImpl::kAXCheckedStateChanged);
+ PostNotification(node, ax::mojom::Event::kCheckedStateChanged);
}
void AXObjectCacheImpl::ListboxOptionStateChanged(HTMLOptionElement* option) {
- PostNotification(option, kAXCheckedStateChanged);
+ PostNotification(option, ax::mojom::Event::kCheckedStateChanged);
}
void AXObjectCacheImpl::ListboxSelectedChildrenChanged(
HTMLSelectElement* select) {
- PostNotification(select, kAXSelectedChildrenChanged);
+ PostNotification(select, ax::mojom::Event::kSelectedChildrenChanged);
}
void AXObjectCacheImpl::ListboxActiveIndexChanged(HTMLSelectElement* select) {
@@ -830,7 +875,7 @@ void AXObjectCacheImpl::ListboxActiveIndexChanged(HTMLSelectElement* select) {
}
void AXObjectCacheImpl::LocationChanged(LayoutObject* layout_object) {
- PostNotification(layout_object, kAXLocationChanged);
+ PostNotification(layout_object, ax::mojom::Event::kLocationChanged);
}
void AXObjectCacheImpl::RadiobuttonRemovedFromGroup(
@@ -848,7 +893,7 @@ void AXObjectCacheImpl::RadiobuttonRemovedFromGroup(
return;
ToAXRadioInput(first_obj)->UpdatePosAndSetSize(1);
- PostNotification(first_obj, kAXAriaAttributeChanged);
+ PostNotification(first_obj, ax::mojom::Event::kAriaAttributeChanged);
ToAXRadioInput(first_obj)->RequestUpdateToNextNode(true);
}
@@ -862,12 +907,12 @@ void AXObjectCacheImpl::HandleLayoutComplete(LayoutObject* layout_object) {
// end of a layout, and it allows an AX notification to be sent when a page
// has its first layout, rather than when the document first loads.
if (AXObject* obj = GetOrCreate(layout_object))
- PostNotification(obj, kAXLayoutComplete);
+ PostNotification(obj, ax::mojom::Event::kLayoutComplete);
}
void AXObjectCacheImpl::HandleClicked(Node* node) {
if (AXObject* obj = GetOrCreate(node))
- PostNotification(obj, kAXClicked);
+ PostNotification(obj, ax::mojom::Event::kClicked);
}
void AXObjectCacheImpl::HandleAttributeChanged(
@@ -875,7 +920,7 @@ void AXObjectCacheImpl::HandleAttributeChanged(
AccessibleNode* accessible_node) {
modification_count_++;
if (AXObject* obj = Get(accessible_node))
- PostNotification(obj, kAXAriaAttributeChanged);
+ PostNotification(obj, ax::mojom::Event::kAriaAttributeChanged);
}
void AXObjectCacheImpl::HandleAriaExpandedChange(Node* node) {
@@ -888,11 +933,11 @@ void AXObjectCacheImpl::HandleAriaSelectedChanged(Node* node) {
if (!obj)
return;
- PostNotification(obj, kAXCheckedStateChanged);
+ PostNotification(obj, ax::mojom::Event::kCheckedStateChanged);
AXObject* listbox = obj->ParentObjectUnignored();
- if (listbox && listbox->RoleValue() == kListBoxRole)
- PostNotification(listbox, kAXSelectedChildrenChanged);
+ if (listbox && listbox->RoleValue() == ax::mojom::Role::kListBox)
+ PostNotification(listbox, ax::mojom::Event::kSelectedChildrenChanged);
}
// This might be the new target of a relation. Handle all possible cases.
@@ -934,8 +979,12 @@ void AXObjectCacheImpl::HandlePossibleRoleChange(Node* node) {
if (!node)
return; // Virtual AOM node.
+ AXObject* obj = Get(node);
+ if (!obj && IsHTMLSelectElement(node))
+ obj = GetOrCreate(node);
+
// Invalidate the current object and make the parent reconsider its children.
- if (AXObject* obj = Get(node)) {
+ if (obj) {
// Save parent for later use.
AXObject* parent = obj->ParentObject();
@@ -978,7 +1027,7 @@ void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
if (attr_name == aria_activedescendantAttr)
HandleActiveDescendantChanged(element);
else if (attr_name == aria_valuenowAttr || attr_name == aria_valuetextAttr)
- PostNotification(element, AXObjectCacheImpl::kAXValueChanged);
+ PostNotification(element, ax::mojom::Event::kValueChanged);
else if (attr_name == aria_labelAttr || attr_name == aria_labeledbyAttr ||
attr_name == aria_labelledbyAttr)
TextChanged(element);
@@ -993,11 +1042,11 @@ void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
else if (attr_name == aria_hiddenAttr)
ChildrenChanged(element->parentNode());
else if (attr_name == aria_invalidAttr)
- PostNotification(element, AXObjectCacheImpl::kAXInvalidStatusChanged);
+ PostNotification(element, ax::mojom::Event::kInvalidStatusChanged);
else if (attr_name == aria_ownsAttr)
ChildrenChanged(element);
else
- PostNotification(element, AXObjectCacheImpl::kAXAriaAttributeChanged);
+ PostNotification(element, ax::mojom::Event::kAriaAttributeChanged);
}
void AXObjectCacheImpl::HandleAutofillStateChanged(Element* elem,
@@ -1023,7 +1072,7 @@ void AXObjectCacheImpl::InlineTextBoxesUpdated(
if (AXObject* obj = Get(layout_object)) {
if (!obj->NeedsToUpdateChildren()) {
obj->SetNeedsToUpdateChildren();
- PostNotification(layout_object, kAXChildrenChanged);
+ PostNotification(layout_object, ax::mojom::Event::kChildrenChanged);
}
}
}
@@ -1093,20 +1142,31 @@ bool IsNodeAriaVisible(Node* node) {
return !is_null && !hidden;
}
-void AXObjectCacheImpl::PostPlatformNotification(AXObject* obj,
- AXNotification notification) {
- if (!obj || !obj->GetDocument() || !obj->DocumentFrameView() ||
- !obj->DocumentFrameView()->GetFrame().GetPage())
+void AXObjectCacheImpl::PostPlatformNotification(
+ AXObject* obj,
+ ax::mojom::Event notification) {
+ if (!document_ || !document_->View() ||
+ !document_->View()->GetFrame().GetPage())
return;
- // Send via WebLocalFrameClient
- WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(
- obj->GetDocument()->AXObjectCacheOwner().GetFrame());
+
+ WebLocalFrameImpl* webframe =
+ WebLocalFrameImpl::FromFrame(document_->AXObjectCacheOwner().GetFrame());
if (webframe && webframe->Client()) {
- webframe->Client()->PostAccessibilityEvent(
- WebAXObject(obj), static_cast<WebAXEvent>(notification));
+ webframe->Client()->PostAccessibilityEvent(WebAXObject(obj), notification);
}
}
+void AXObjectCacheImpl::MarkAXObjectDirty(AXObject* obj, bool subtree) {
+ if (!document_ || !document_->View() ||
+ !document_->View()->GetFrame().GetPage())
+ return;
+
+ WebLocalFrameImpl* webframe =
+ WebLocalFrameImpl::FromFrame(document_->AXObjectCacheOwner().GetFrame());
+ if (webframe && webframe->Client())
+ webframe->Client()->MarkWebAXObjectDirty(WebAXObject(obj), subtree);
+}
+
void AXObjectCacheImpl::HandleFocusedUIElementChanged(Node* old_focused_node,
Node* new_focused_node) {
if (!new_focused_node)
@@ -1122,12 +1182,12 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged(Node* old_focused_node,
AXObject* old_focused_object = Get(old_focused_node);
- PostPlatformNotification(old_focused_object, kAXBlur);
- PostPlatformNotification(focused_object, kAXFocusedUIElementChanged);
+ PostPlatformNotification(old_focused_object, ax::mojom::Event::kBlur);
+ PostPlatformNotification(focused_object, ax::mojom::Event::kFocus);
}
void AXObjectCacheImpl::HandleInitialFocus() {
- PostNotification(document_, kAXFocusedUIElementChanged);
+ PostNotification(document_, ax::mojom::Event::kFocus);
}
void AXObjectCacheImpl::HandleEditableTextContentChanged(Node* node) {
@@ -1145,13 +1205,13 @@ void AXObjectCacheImpl::HandleEditableTextContentChanged(Node* node) {
while (obj && !obj->IsNativeTextControl() && !obj->IsNonNativeTextControl())
obj = obj->ParentObject();
- PostNotification(obj, kAXValueChanged);
+ PostNotification(obj, ax::mojom::Event::kValueChanged);
}
void AXObjectCacheImpl::HandleScaleAndLocationChanged(Document* document) {
if (!document)
return;
- PostNotification(document, kAXLocationChanged);
+ PostNotification(document, ax::mojom::Event::kLocationChanged);
}
void AXObjectCacheImpl::HandleTextFormControlChanged(Node* node) {
@@ -1170,7 +1230,7 @@ void AXObjectCacheImpl::HandleTextMarkerDataAdded(Node* start, Node* end) {
}
void AXObjectCacheImpl::HandleValueChanged(Node* node) {
- PostNotification(node, kAXValueChanged);
+ PostNotification(node, ax::mojom::Event::kValueChanged);
}
void AXObjectCacheImpl::HandleUpdateActiveMenuOption(LayoutMenuList* menu_list,
@@ -1199,12 +1259,12 @@ void AXObjectCacheImpl::DidHideMenuListPopup(LayoutMenuList* menu_list) {
}
void AXObjectCacheImpl::HandleLoadComplete(Document* document) {
- PostNotification(GetOrCreate(document), kAXLoadComplete);
+ PostNotification(GetOrCreate(document), ax::mojom::Event::kLoadComplete);
AddPermissionStatusListener();
}
void AXObjectCacheImpl::HandleLayoutComplete(Document* document) {
- PostNotification(GetOrCreate(document), kAXLayoutComplete);
+ PostNotification(GetOrCreate(document), ax::mojom::Event::kLayoutComplete);
}
void AXObjectCacheImpl::HandleScrolledToAnchor(const Node* anchor_node) {
@@ -1215,26 +1275,27 @@ void AXObjectCacheImpl::HandleScrolledToAnchor(const Node* anchor_node) {
return;
if (obj->AccessibilityIsIgnored())
obj = obj->ParentObjectUnignored();
- PostPlatformNotification(obj, kAXScrolledToAnchor);
+ PostPlatformNotification(obj, ax::mojom::Event::kScrolledToAnchor);
}
void AXObjectCacheImpl::HandleScrollPositionChanged(
LocalFrameView* frame_view) {
AXObject* target_ax_object =
GetOrCreate(frame_view->GetFrame().GetDocument());
- PostPlatformNotification(target_ax_object, kAXScrollPositionChanged);
+ PostPlatformNotification(target_ax_object,
+ ax::mojom::Event::kScrollPositionChanged);
}
void AXObjectCacheImpl::HandleScrollPositionChanged(
LayoutObject* layout_object) {
PostPlatformNotification(GetOrCreate(layout_object),
- kAXScrollPositionChanged);
+ ax::mojom::Event::kScrollPositionChanged);
}
const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) {
AXObject* obj = GetOrCreate(node);
if (!obj)
- return AXObject::RoleName(kUnknownRole);
+ return AXObject::RoleName(ax::mojom::Role::kUnknown);
return AXObject::RoleName(obj->RoleValue());
}
@@ -1256,7 +1317,7 @@ void AXObjectCacheImpl::OnTouchAccessibilityHover(const IntPoint& location) {
hit->GetLayoutObject()->IsLayoutEmbeddedContent())
return;
- PostPlatformNotification(hit, kAXHover);
+ PostPlatformNotification(hit, ax::mojom::Event::kHover);
}
}
@@ -1323,7 +1384,7 @@ void AXObjectCacheImpl::RequestAOMEventListenerPermission() {
permission_service_->RequestPermission(
CreatePermissionDescriptor(
mojom::blink::PermissionName::ACCESSIBILITY_EVENTS),
- Frame::HasTransientUserActivation(document_->GetFrame()),
+ LocalFrame::HasTransientUserActivation(document_->GetFrame()),
WTF::Bind(&AXObjectCacheImpl::OnPermissionStatusChange,
WrapPersistent(this)));
}
@@ -1340,61 +1401,9 @@ void AXObjectCacheImpl::Trace(blink::Visitor* visitor) {
visitor->Trace(objects_);
visitor->Trace(notifications_to_post_);
+ visitor->Trace(nodes_changed_during_layout_);
AXObjectCache::Trace(visitor);
}
-STATIC_ASSERT_ENUM(kWebAXEventActiveDescendantChanged,
- AXObjectCacheImpl::kAXActiveDescendantChanged);
-STATIC_ASSERT_ENUM(kWebAXEventAriaAttributeChanged,
- AXObjectCacheImpl::kAXAriaAttributeChanged);
-STATIC_ASSERT_ENUM(kWebAXEventAutocorrectionOccured,
- AXObjectCacheImpl::kAXAutocorrectionOccured);
-STATIC_ASSERT_ENUM(kWebAXEventBlur, AXObjectCacheImpl::kAXBlur);
-STATIC_ASSERT_ENUM(kWebAXEventCheckedStateChanged,
- AXObjectCacheImpl::kAXCheckedStateChanged);
-STATIC_ASSERT_ENUM(kWebAXEventChildrenChanged,
- AXObjectCacheImpl::kAXChildrenChanged);
-STATIC_ASSERT_ENUM(kWebAXEventClicked, AXObjectCacheImpl::kAXClicked);
-STATIC_ASSERT_ENUM(kWebAXEventDocumentSelectionChanged,
- AXObjectCacheImpl::kAXDocumentSelectionChanged);
-STATIC_ASSERT_ENUM(kWebAXEventDocumentTitleChanged,
- AXObjectCacheImpl::kAXDocumentTitleChanged);
-STATIC_ASSERT_ENUM(kWebAXEventExpandedChanged,
- AXObjectCacheImpl::kAXExpandedChanged);
-STATIC_ASSERT_ENUM(kWebAXEventFocus,
- AXObjectCacheImpl::kAXFocusedUIElementChanged);
-STATIC_ASSERT_ENUM(kWebAXEventHide, AXObjectCacheImpl::kAXHide);
-STATIC_ASSERT_ENUM(kWebAXEventHover, AXObjectCacheImpl::kAXHover);
-STATIC_ASSERT_ENUM(kWebAXEventInvalidStatusChanged,
- AXObjectCacheImpl::kAXInvalidStatusChanged);
-STATIC_ASSERT_ENUM(kWebAXEventLayoutComplete,
- AXObjectCacheImpl::kAXLayoutComplete);
-STATIC_ASSERT_ENUM(kWebAXEventLiveRegionChanged,
- AXObjectCacheImpl::kAXLiveRegionChanged);
-STATIC_ASSERT_ENUM(kWebAXEventLoadComplete, AXObjectCacheImpl::kAXLoadComplete);
-STATIC_ASSERT_ENUM(kWebAXEventLocationChanged,
- AXObjectCacheImpl::kAXLocationChanged);
-STATIC_ASSERT_ENUM(kWebAXEventMenuListItemSelected,
- AXObjectCacheImpl::kAXMenuListItemSelected);
-STATIC_ASSERT_ENUM(kWebAXEventMenuListItemUnselected,
- AXObjectCacheImpl::kAXMenuListItemUnselected);
-STATIC_ASSERT_ENUM(kWebAXEventMenuListValueChanged,
- AXObjectCacheImpl::kAXMenuListValueChanged);
-STATIC_ASSERT_ENUM(kWebAXEventRowCollapsed, AXObjectCacheImpl::kAXRowCollapsed);
-STATIC_ASSERT_ENUM(kWebAXEventRowCountChanged,
- AXObjectCacheImpl::kAXRowCountChanged);
-STATIC_ASSERT_ENUM(kWebAXEventRowExpanded, AXObjectCacheImpl::kAXRowExpanded);
-STATIC_ASSERT_ENUM(kWebAXEventScrollPositionChanged,
- AXObjectCacheImpl::kAXScrollPositionChanged);
-STATIC_ASSERT_ENUM(kWebAXEventScrolledToAnchor,
- AXObjectCacheImpl::kAXScrolledToAnchor);
-STATIC_ASSERT_ENUM(kWebAXEventSelectedChildrenChanged,
- AXObjectCacheImpl::kAXSelectedChildrenChanged);
-STATIC_ASSERT_ENUM(kWebAXEventSelectedTextChanged,
- AXObjectCacheImpl::kAXSelectedTextChanged);
-STATIC_ASSERT_ENUM(kWebAXEventShow, AXObjectCacheImpl::kAXShow);
-STATIC_ASSERT_ENUM(kWebAXEventTextChanged, AXObjectCacheImpl::kAXTextChanged);
-STATIC_ASSERT_ENUM(kWebAXEventValueChanged, AXObjectCacheImpl::kAXValueChanged);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 185c3fe3d47..cd015ac7347 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "ui/accessibility/ax_enums.mojom-blink.h"
namespace blink {
@@ -56,40 +57,6 @@ class MODULES_EXPORT AXObjectCacheImpl
public:
static AXObjectCache* Create(Document&);
- enum AXNotification {
- kAXActiveDescendantChanged,
- kAXAriaAttributeChanged,
- kAXAutocorrectionOccured,
- kAXBlur,
- kAXCheckedStateChanged,
- kAXChildrenChanged,
- kAXClicked,
- kAXDocumentSelectionChanged,
- kAXDocumentTitleChanged,
- kAXExpandedChanged,
- kAXFocusedUIElementChanged,
- kAXHide,
- kAXHover,
- kAXInvalidStatusChanged,
- kAXLayoutComplete,
- kAXLiveRegionChanged,
- kAXLoadComplete,
- kAXLocationChanged,
- kAXMenuListItemSelected,
- kAXMenuListItemUnselected,
- kAXMenuListValueChanged,
- kAXRowCollapsed,
- kAXRowCountChanged,
- kAXRowExpanded,
- kAXScrollPositionChanged,
- kAXScrolledToAnchor,
- kAXSelectedChildrenChanged,
- kAXSelectedTextChanged,
- kAXShow,
- kAXTextChanged,
- kAXValueChanged
- };
-
explicit AXObjectCacheImpl(Document&);
~AXObjectCacheImpl() override;
void Trace(blink::Visitor*) override;
@@ -161,6 +128,7 @@ class MODULES_EXPORT AXObjectCacheImpl
const LayoutRect&) override;
void InlineTextBoxesUpdated(LineLayoutItem) override;
+ void ProcessUpdatesAfterLayout(Document&) override;
// Called when the scroll offset changes.
void HandleScrollPositionChanged(LocalFrameView*) override;
@@ -179,7 +147,7 @@ class MODULES_EXPORT AXObjectCacheImpl
AXObject* Root();
// used for objects without backing elements
- AXObject* GetOrCreate(AccessibilityRole);
+ AXObject* GetOrCreate(ax::mojom::Role);
AXObject* GetOrCreate(AccessibleNode*);
AXObject* GetOrCreate(LayoutObject*) override;
AXObject* GetOrCreate(const Node*);
@@ -219,9 +187,10 @@ class MODULES_EXPORT AXObjectCacheImpl
// values are cached as long as the modification count hasn't changed.
int ModificationCount() const { return modification_count_; }
- void PostNotification(LayoutObject*, AXNotification);
- void PostNotification(Node*, AXNotification);
- void PostNotification(AXObject*, AXNotification);
+ void PostNotification(LayoutObject*, ax::mojom::Event);
+ void PostNotification(Node*, ax::mojom::Event);
+ void PostNotification(AXObject*, ax::mojom::Event);
+ void MarkAXObjectDirty(AXObject*, bool subtree);
//
// Aria-owns support.
@@ -258,7 +227,7 @@ class MODULES_EXPORT AXObjectCacheImpl
void RequestAOMEventListenerPermission();
protected:
- void PostPlatformNotification(AXObject*, AXNotification);
+ void PostPlatformNotification(AXObject*, ax::mojom::Event);
void LabelChanged(Element*);
AXObject* CreateFromRenderer(LayoutObject*);
@@ -286,7 +255,7 @@ class MODULES_EXPORT AXObjectCacheImpl
#endif
TaskRunnerTimer<AXObjectCacheImpl> notification_post_timer_;
- HeapVector<std::pair<Member<AXObject>, AXNotification>>
+ HeapVector<std::pair<Member<AXObject>, ax::mojom::Event>>
notifications_to_post_;
void NotificationPostTimerFired(TimerBase*);
@@ -326,6 +295,8 @@ class MODULES_EXPORT AXObjectCacheImpl
mojom::blink::PermissionServicePtr permission_service_;
mojo::Binding<mojom::blink::PermissionObserver> permission_observer_binding_;
+ HeapVector<Member<Node>> nodes_changed_during_layout_;
+
DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl);
};
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
index 783667c202a..ed63425c53b 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
@@ -59,25 +59,22 @@ TEST_F(AccessibilityTest, SimpleTreeNavigation) {
EXPECT_EQ(button, root->DeepestLastChild());
ASSERT_NE(nullptr, paragraph->FirstChild());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole,
- paragraph->FirstChild()->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->FirstChild()->RoleValue());
ASSERT_NE(nullptr, paragraph->LastChild());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole,
- paragraph->LastChild()->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->LastChild()->RoleValue());
ASSERT_NE(nullptr, paragraph->DeepestFirstChild());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole,
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
paragraph->DeepestFirstChild()->RoleValue());
ASSERT_NE(nullptr, paragraph->DeepestLastChild());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole,
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
paragraph->DeepestLastChild()->RoleValue());
EXPECT_EQ(paragraph->PreviousSibling(), input);
EXPECT_EQ(paragraph, input->NextSibling());
ASSERT_NE(nullptr, br->NextSibling());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole, br->NextSibling()->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kStaticText, br->NextSibling()->RoleValue());
ASSERT_NE(nullptr, br->PreviousSibling());
- EXPECT_EQ(AccessibilityRole::kStaticTextRole,
- br->PreviousSibling()->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kStaticText, br->PreviousSibling()->RoleValue());
}
TEST_F(AccessibilityTest, AXObjectComparisonOperators) {
@@ -134,11 +131,11 @@ TEST_F(AccessibilityTest, AXObjectAncestorsIterator) {
ASSERT_NE(nullptr, bold);
AXObject* br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, br);
- ASSERT_EQ(AccessibilityRole::kLineBreakRole, br->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kLineBreak, br->RoleValue());
AXObject::AncestorsIterator iter = br->AncestorsBegin();
EXPECT_EQ(*paragraph, *iter);
- EXPECT_EQ(AccessibilityRole::kParagraphRole, iter->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kParagraph, iter->RoleValue());
EXPECT_EQ(*root, *++iter);
EXPECT_EQ(*root, *iter++);
EXPECT_EQ(br->AncestorsEnd(), ++iter);
@@ -157,13 +154,13 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) {
++iter; // Skip the generic container which is an ignored object.
EXPECT_NE(GetAXObjectCache().InOrderTraversalEnd(), iter);
EXPECT_EQ(*button, *++iter);
- EXPECT_EQ(AccessibilityRole::kButtonRole, iter->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kButton, iter->RoleValue());
EXPECT_EQ(*button, *iter++);
EXPECT_EQ(GetAXObjectCache().InOrderTraversalEnd(), iter);
EXPECT_EQ(*button, *--iter);
EXPECT_EQ(*button, *iter--);
--iter; // Skip the generic container which is an ignored object.
- EXPECT_EQ(AccessibilityRole::kWebAreaRole, iter->RoleValue());
+ EXPECT_EQ(ax::mojom::Role::kRootWebArea, iter->RoleValue());
EXPECT_EQ(GetAXObjectCache().InOrderTraversalBegin(), iter);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
index fe5b0e1b185..a2447816857 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
@@ -39,7 +39,7 @@ enum class AXPositionAdjustmentBehavior { kMoveLeft, kMoveRight };
// between two characters. Another way of calling these types of positions is
// object anchored and text anchored.
class MODULES_EXPORT AXPosition final {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
//
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
index ce0fbac4342..90d30a05e25 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -90,7 +90,7 @@ TEST_F(AccessibilityTest, PositionInText) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionInTextObject(*ax_static_text, 3);
@@ -113,7 +113,7 @@ TEST_F(AccessibilityTest, PositionBeforeText) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionBeforeObject(*ax_static_text);
@@ -136,7 +136,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithFirstLetterCSSRule) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionBeforeObject(*ax_static_text);
@@ -160,7 +160,7 @@ TEST_F(AccessibilityTest, PositionAfterText) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionAfterObject(*ax_static_text);
@@ -177,10 +177,10 @@ TEST_F(AccessibilityTest, PositionBeforeLineBreak) {
SetBodyInnerHTML(R"HTML(Hello<br id="br">there)HTML");
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
- ASSERT_EQ(AccessibilityRole::kLineBreakRole, ax_br->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
const AXObject* ax_div = ax_br->ParentObjectUnignored();
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const auto ax_position = AXPosition::CreatePositionBeforeObject(*ax_br);
EXPECT_FALSE(ax_position.IsTextPosition());
@@ -200,13 +200,13 @@ TEST_F(AccessibilityTest, PositionAfterLineBreak) {
SetBodyInnerHTML(R"HTML(Hello<br id="br">there)HTML");
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
- ASSERT_EQ(AccessibilityRole::kLineBreakRole, ax_br->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
const AXObject* ax_div = ax_br->ParentObjectUnignored();
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position = AXPosition::CreatePositionAfterObject(*ax_br);
EXPECT_FALSE(ax_position.IsTextPosition());
@@ -228,10 +228,10 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainer) {
ASSERT_NE(nullptr, div);
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position = AXPosition::CreateFirstPositionInObject(*ax_div);
const auto position = ax_position.ToPositionWithAffinity();
@@ -250,7 +250,7 @@ TEST_F(AccessibilityTest, LastPositionInDivContainer) {
ASSERT_NE(nullptr, div);
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const auto ax_position = AXPosition::CreateLastPositionInObject(*ax_div);
const auto position = ax_position.ToPositionWithAffinity();
@@ -269,7 +269,7 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainer) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreateFirstPositionInObject(*ax_static_text);
@@ -289,7 +289,7 @@ TEST_F(AccessibilityTest, LastPositionInTextContainer) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreateLastPositionInObject(*ax_static_text);
@@ -385,7 +385,7 @@ TEST_F(AccessibilityTest, PositionInTextWithWhiteSpace) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionInTextObject(*ax_static_text, 3);
@@ -406,7 +406,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithWhiteSpace) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionBeforeObject(*ax_static_text);
@@ -427,7 +427,7 @@ TEST_F(AccessibilityTest, PositionAfterTextWithWhiteSpace) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->LastChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreatePositionAfterObject(*ax_static_text);
@@ -444,10 +444,10 @@ TEST_F(AccessibilityTest, PositionBeforeLineBreakWithWhiteSpace) {
SetBodyInnerHTML(R"HTML(Hello <br id="br"> there)HTML");
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
- ASSERT_EQ(AccessibilityRole::kLineBreakRole, ax_br->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
const AXObject* ax_div = ax_br->ParentObjectUnignored();
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const auto ax_position = AXPosition::CreatePositionBeforeObject(*ax_br);
EXPECT_FALSE(ax_position.IsTextPosition());
@@ -467,13 +467,13 @@ TEST_F(AccessibilityTest, PositionAfterLineBreakWithWhiteSpace) {
SetBodyInnerHTML(R"HTML(Hello <br id="br"> there)HTML");
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
- ASSERT_EQ(AccessibilityRole::kLineBreakRole, ax_br->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
const AXObject* ax_div = ax_br->ParentObjectUnignored();
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position = AXPosition::CreatePositionAfterObject(*ax_br);
EXPECT_FALSE(ax_position.IsTextPosition());
@@ -495,10 +495,10 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainerWithWhiteSpace) {
ASSERT_NE(nullptr, div);
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position = AXPosition::CreateFirstPositionInObject(*ax_div);
const auto position = ax_position.ToPositionWithAffinity();
@@ -517,7 +517,7 @@ TEST_F(AccessibilityTest, LastPositionInDivContainerWithWhiteSpace) {
ASSERT_NE(nullptr, div);
const AXObject* ax_div = GetAXObjectByElementId("div");
ASSERT_NE(nullptr, ax_div);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_div->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue());
const auto ax_position = AXPosition::CreateLastPositionInObject(*ax_div);
const auto position = ax_position.ToPositionWithAffinity();
@@ -536,7 +536,7 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainerWithWhiteSpace) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreateFirstPositionInObject(*ax_static_text);
@@ -556,7 +556,7 @@ TEST_F(AccessibilityTest, LastPositionInTextContainerWithWhiteSpace) {
ASSERT_TRUE(text->IsTextNode());
const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const auto ax_position =
AXPosition::CreateLastPositionInObject(*ax_static_text);
@@ -579,7 +579,7 @@ TEST_F(AccessibilityTest, AXPositionFromDOMPositionWithWhiteSpace) {
ASSERT_EQ(15U, text->textContent().length());
const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
const Position position_at_start(*text, 0);
const auto ax_position_at_start = AXPosition::FromPosition(position_at_start);
@@ -626,7 +626,7 @@ TEST_F(AccessibilityTest, PositionInTextWithAffinity) {
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue());
// Converting from AX to DOM positions should maintain affinity.
const auto ax_position = AXPosition::CreatePositionInTextObject(
@@ -664,14 +664,14 @@ TEST_F(AccessibilityTest, PositionInHTMLLabel) {
const AXObject* ax_root = GetAXRootObject();
ASSERT_NE(nullptr, ax_root);
- ASSERT_EQ(AccessibilityRole::kWebAreaRole, ax_root->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kRootWebArea, ax_root->RoleValue());
// The HTML label element should be ignored.
const AXObject* ax_label = GetAXObjectByElementId("label");
ASSERT_NE(nullptr, ax_label);
ASSERT_TRUE(ax_label->AccessibilityIsIgnored());
const AXObject* ax_paragraph = GetAXObjectByElementId("paragraph");
ASSERT_NE(nullptr, ax_paragraph);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_paragraph->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_paragraph->RoleValue());
// All of the following DOM positions should be ignored in the accessibility
// tree.
@@ -715,11 +715,11 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) {
const AXObject* ax_root = GetAXRootObject();
ASSERT_NE(nullptr, ax_root);
- ASSERT_EQ(AccessibilityRole::kWebAreaRole, ax_root->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kRootWebArea, ax_root->RoleValue());
ASSERT_EQ(1, ax_root->ChildCount());
const AXObject* ax_visible = ax_root->FirstChild();
ASSERT_NE(nullptr, ax_visible);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_visible->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_visible->RoleValue());
// The fact that there is a hidden object before |visible| should not affect
// setting a position before it.
@@ -795,10 +795,10 @@ TEST_F(AccessibilityTest, BeforePositionInARIAHiddenShouldSkipARIAHidden) {
const AXObject* ax_before = GetAXObjectByElementId("before");
ASSERT_NE(nullptr, ax_before);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_before->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_before->RoleValue());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
ASSERT_NE(nullptr, GetAXObjectByElementId("ariaHidden"));
ASSERT_TRUE(GetAXObjectByElementId("ariaHidden")->AccessibilityIsIgnored());
@@ -829,7 +829,7 @@ TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) {
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
ASSERT_NE(nullptr, GetAXObjectByElementId("ariaHidden"));
ASSERT_TRUE(GetAXObjectByElementId("ariaHidden")->AccessibilityIsIgnored());
@@ -870,11 +870,11 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) {
const AXObject* ax_container = GetAXObjectByElementId("container");
ASSERT_NE(nullptr, ax_container);
- ASSERT_EQ(AccessibilityRole::kMainRole, ax_container->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kMain, ax_container->RoleValue());
ASSERT_EQ(2, ax_container->ChildCount());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
ASSERT_NE(nullptr, GetAXObjectByElementId("ariaHidden"));
ASSERT_TRUE(GetAXObjectByElementId("ariaHidden")->AccessibilityIsIgnored());
@@ -929,16 +929,16 @@ TEST_F(AccessibilityTest, PositionInCanvas) {
const AXObject* ax_canvas_1 = GetAXObjectByElementId("canvas1");
ASSERT_NE(nullptr, ax_canvas_1);
- ASSERT_EQ(AccessibilityRole::kCanvasRole, ax_canvas_1->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kCanvas, ax_canvas_1->RoleValue());
const AXObject* ax_text = ax_canvas_1->FirstChild();
ASSERT_NE(nullptr, ax_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
const AXObject* ax_canvas_2 = GetAXObjectByElementId("canvas2");
ASSERT_NE(nullptr, ax_canvas_2);
- ASSERT_EQ(AccessibilityRole::kCanvasRole, ax_canvas_2->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kCanvas, ax_canvas_2->RoleValue());
const AXObject* ax_button = GetAXObjectByElementId("button");
ASSERT_NE(nullptr, ax_button);
- ASSERT_EQ(AccessibilityRole::kButtonRole, ax_button->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kButton, ax_button->RoleValue());
const auto ax_position_1 =
AXPosition::CreateFirstPositionInObject(*ax_canvas_1);
@@ -1020,11 +1020,11 @@ TEST_F(AccessibilityTest, PositionBeforeListMarker) {
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
- ASSERT_EQ(AccessibilityRole::kListItemRole, ax_item->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue());
ASSERT_EQ(2, ax_item->ChildCount());
const AXObject* ax_marker = ax_item->FirstChild();
ASSERT_NE(nullptr, ax_marker);
- ASSERT_EQ(AccessibilityRole::kListMarkerRole, ax_marker->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue());
//
// Test adjusting invalid DOM positions to the left.
@@ -1100,14 +1100,14 @@ TEST_F(AccessibilityTest, PositionAfterListMarker) {
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
- ASSERT_EQ(AccessibilityRole::kListItemRole, ax_item->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue());
ASSERT_EQ(2, ax_item->ChildCount());
const AXObject* ax_marker = ax_item->FirstChild();
ASSERT_NE(nullptr, ax_marker);
- ASSERT_EQ(AccessibilityRole::kListMarkerRole, ax_marker->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue());
const AXObject* ax_text = ax_item->LastChild();
ASSERT_NE(nullptr, ax_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
const auto ax_position = AXPosition::CreatePositionAfterObject(*ax_marker);
const auto position = ax_position.ToPositionWithAffinity();
@@ -1133,17 +1133,17 @@ TEST_F(AccessibilityTest, PositionInCSSContent) {
const AXObject* ax_quote = GetAXObjectByElementId("quote");
ASSERT_NE(nullptr, ax_quote);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_quote->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_quote->RoleValue());
ASSERT_EQ(3, ax_quote->ChildCount());
const AXObject* ax_css_before = ax_quote->FirstChild();
ASSERT_NE(nullptr, ax_css_before);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_css_before->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_before->RoleValue());
const AXObject* ax_text = *(ax_quote->Children().begin() + 1);
ASSERT_NE(nullptr, ax_text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
const AXObject* ax_css_after = ax_quote->LastChild();
ASSERT_NE(nullptr, ax_css_after);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_css_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_after->RoleValue());
const auto ax_position_before =
AXPosition::CreateFirstPositionInObject(*ax_css_before);
@@ -1178,10 +1178,10 @@ TEST_F(AccessibilityTest, PositionBeforeAndAfterTable) {
ASSERT_NE(nullptr, after);
const AXObject* ax_table = GetAXObjectByElementId("table");
ASSERT_NE(nullptr, ax_table);
- ASSERT_EQ(AccessibilityRole::kTableRole, ax_table->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kTable, ax_table->RoleValue());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
const auto ax_position_before =
AXPosition::CreatePositionBeforeObject(*ax_table);
@@ -1227,10 +1227,10 @@ TEST_F(AccessibilityTest, PositionAtStartAndEndOfTable) {
const AXObject* ax_table = GetAXObjectByElementId("table");
ASSERT_NE(nullptr, ax_table);
- ASSERT_EQ(AccessibilityRole::kTableRole, ax_table->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kTable, ax_table->RoleValue());
const AXObject* ax_header_row = GetAXObjectByElementId("headerRow");
ASSERT_NE(nullptr, ax_header_row);
- ASSERT_EQ(AccessibilityRole::kRowRole, ax_header_row->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kRow, ax_header_row->RoleValue());
const auto ax_position_at_start =
AXPosition::CreateFirstPositionInObject(*ax_table);
@@ -1270,13 +1270,11 @@ TEST_F(AccessibilityTest, PositionInTableHeader) {
const AXObject* ax_first_header_cell =
GetAXObjectByElementId("firstHeaderCell");
ASSERT_NE(nullptr, ax_first_header_cell);
- ASSERT_EQ(AccessibilityRole::kColumnHeaderRole,
- ax_first_header_cell->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kColumnHeader, ax_first_header_cell->RoleValue());
const AXObject* ax_last_header_cell =
GetAXObjectByElementId("lastHeaderCell");
ASSERT_NE(nullptr, ax_last_header_cell);
- ASSERT_EQ(AccessibilityRole::kColumnHeaderRole,
- ax_last_header_cell->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kColumnHeader, ax_last_header_cell->RoleValue());
const auto ax_position_before =
AXPosition::CreatePositionBeforeObject(*ax_first_header_cell);
@@ -1317,10 +1315,10 @@ TEST_F(AccessibilityTest, PositionInTableRow) {
const AXObject* ax_first_cell = GetAXObjectByElementId("firstCell");
ASSERT_NE(nullptr, ax_first_cell);
- ASSERT_EQ(AccessibilityRole::kRowHeaderRole, ax_first_cell->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kRowHeader, ax_first_cell->RoleValue());
const AXObject* ax_last_cell = GetAXObjectByElementId("lastCell");
ASSERT_NE(nullptr, ax_last_cell);
- ASSERT_EQ(AccessibilityRole::kCellRole, ax_last_cell->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kCell, ax_last_cell->RoleValue());
const auto ax_position_before =
AXPosition::CreatePositionBeforeObject(*ax_first_cell);
@@ -1361,14 +1359,14 @@ TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) {
const AXObject* ax_parent = GetAXObjectByElementId("aomParent");
ASSERT_NE(nullptr, ax_parent);
- ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_parent->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_parent->RoleValue());
ASSERT_EQ(1, ax_parent->ChildCount());
const AXObject* ax_button = ax_parent->FirstChild();
ASSERT_NE(nullptr, ax_button);
- ASSERT_EQ(AccessibilityRole::kButtonRole, ax_button->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kButton, ax_button->RoleValue());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
- ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue());
const auto ax_position_before =
AXPosition::CreatePositionBeforeObject(*ax_button);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
index 00c46041ab5..3e8c77033fd 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
@@ -40,10 +40,10 @@ AXProgressIndicator* AXProgressIndicator::Create(
return new AXProgressIndicator(layout_object, ax_object_cache);
}
-AccessibilityRole AXProgressIndicator::DetermineAccessibilityRole() {
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ax::mojom::Role AXProgressIndicator::DetermineAccessibilityRole() {
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
- return kProgressIndicatorRole;
+ return ax::mojom::Role::kProgressIndicator;
}
bool AXProgressIndicator::ComputeAccessibilityIsIgnored(
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h
index 6296991b509..c4e2ab9aaa7 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.h
@@ -35,7 +35,7 @@ class AXProgressIndicator final : public AXLayoutObject {
static AXProgressIndicator* Create(LayoutProgress*, AXObjectCacheImpl&);
private:
- AccessibilityRole DetermineAccessibilityRole() final;
+ ax::mojom::Role DetermineAccessibilityRole() final;
bool IsProgressIndicator() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
index 93a91192e75..dd1c41a885f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
@@ -53,7 +53,7 @@ void AXRadioInput::RequestUpdateToNextNode(bool forward) {
ToAXRadioInput(next_axobject)->UpdatePosAndSetSize(position);
AXObjectCache().PostNotification(next_axobject,
- AXObjectCacheImpl::kAXAriaAttributeChanged);
+ ax::mojom::Event::kAriaAttributeChanged);
ToAXRadioInput(next_axobject)->RequestUpdateToNextNode(forward);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_range.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_range.h
index b3b381c6202..a5cb18249e9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_range.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_range.h
@@ -18,7 +18,7 @@ namespace blink {
class AXObject;
class MODULES_EXPORT AXRange final {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
AXRange(const AXPosition& start, const AXPosition& end);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
index 342bb0ba16f..25ade2647a9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc
@@ -24,12 +24,12 @@ TEST_F(AccessibilityTest, CommonAncestorContainerOfRange) {
ASSERT_NE(nullptr, paragraph);
const AXObject* text1 = paragraph->FirstChild();
ASSERT_NE(nullptr, text1);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, text1->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, text1->RoleValue());
const AXObject* br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, br);
const AXObject* text2 = paragraph->LastChild();
ASSERT_NE(nullptr, text2);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, text2->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, text2->RoleValue());
const AXObject* button = GetAXObjectByElementId("button");
ASSERT_NE(nullptr, button);
@@ -54,7 +54,7 @@ TEST_F(AccessibilityTest, IsCollapsedRange) {
ASSERT_NE(nullptr, paragraph);
const AXObject* text = paragraph->FirstChild();
ASSERT_NE(nullptr, text);
- ASSERT_EQ(AccessibilityRole::kStaticTextRole, text->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kStaticText, text->RoleValue());
const AXRange paragraph_range(
AXPosition::CreateLastPositionInObject(*paragraph),
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index 74902bd58c3..9a01cb2ba90 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -69,9 +69,8 @@ bool AXRelationCache::IsValidOwnsRelation(AXObject* owner,
void AXRelationCache::UnmapOwnedChildren(const AXObject* owner,
const Vector<AXID> child_ids) {
- for (size_t i = 0; i < child_ids.size(); ++i) {
+ for (AXID removed_child_id : child_ids) {
// Find the AXObject for the child that this owner no longer owns.
- AXID removed_child_id = child_ids[i];
AXObject* removed_child = ObjectFromAXID(removed_child_id);
// It's possible that this child has already been owned by some other
@@ -102,10 +101,7 @@ void AXRelationCache::UnmapOwnedChildren(const AXObject* owner,
void AXRelationCache::MapOwnedChildren(const AXObject* owner,
const Vector<AXID> child_ids) {
- for (size_t i = 0; i < child_ids.size(); ++i) {
- // Find the AXObject for the child that will now be a child of this
- // owner.
- AXID added_child_id = child_ids[i];
+ for (AXID added_child_id : child_ids) {
AXObject* added_child = ObjectFromAXID(added_child_id);
// Add this child to the mapping from child to owner.
@@ -233,8 +229,8 @@ void AXRelationCache::UpdateRelatedText(Node* node) {
void AXRelationCache::RemoveAXID(AXID obj_id) {
if (aria_owner_to_children_mapping_.Contains(obj_id)) {
Vector<AXID> child_axids = aria_owner_to_children_mapping_.at(obj_id);
- for (size_t i = 0; i < child_axids.size(); ++i)
- aria_owned_child_to_owner_mapping_.erase(child_axids[i]);
+ for (AXID child_axid : child_axids)
+ aria_owned_child_to_owner_mapping_.erase(child_axid);
aria_owner_to_children_mapping_.erase(obj_id);
}
aria_owned_child_to_owner_mapping_.erase(obj_id);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
index 4571bc5b89b..fbcecc8843c 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
@@ -26,7 +26,7 @@ enum class AXSelectionBehavior {
};
class MODULES_EXPORT AXSelection final {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
class Builder;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
index cb09e9c2029..aa00ce8b023 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc
@@ -47,11 +47,11 @@ AXSlider* AXSlider::Create(LayoutObject* layout_object,
return new AXSlider(layout_object, ax_object_cache);
}
-AccessibilityRole AXSlider::DetermineAccessibilityRole() {
- if ((aria_role_ = DetermineAriaRoleAttribute()) != kUnknownRole)
+ax::mojom::Role AXSlider::DetermineAccessibilityRole() {
+ if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
return aria_role_;
- return kSliderRole;
+ return ax::mojom::Role::kSlider;
}
AccessibilityOrientation AXSlider::Orientation() const {
@@ -88,8 +88,8 @@ void AXSlider::AddChildren() {
AXObjectCacheImpl& cache = AXObjectCache();
- AXSliderThumb* thumb =
- static_cast<AXSliderThumb*>(cache.GetOrCreate(kSliderThumbRole));
+ AXSliderThumb* thumb = static_cast<AXSliderThumb*>(
+ cache.GetOrCreate(ax::mojom::Role::kSliderThumb));
thumb->SetParent(this);
// Before actually adding the value indicator to the hierarchy,
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.h
index eaf5c12c82e..ab68e7145a8 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.h
@@ -50,7 +50,7 @@ class AXSlider : public AXLayoutObject {
HTMLInputElement* GetInputElement() const;
AXObject* ElementAccessibilityHitTest(const IntPoint&) const final;
- AccessibilityRole DetermineAccessibilityRole() final;
+ ax::mojom::Role DetermineAccessibilityRole() final;
bool IsSlider() const final { return true; }
bool IsControl() const final { return true; }
@@ -67,7 +67,9 @@ class AXSliderThumb final : public AXMockObject {
static AXSliderThumb* Create(AXObjectCacheImpl&);
~AXSliderThumb() override = default;
- AccessibilityRole RoleValue() const override { return kSliderThumbRole; }
+ ax::mojom::Role RoleValue() const override {
+ return ax::mojom::Role::kSliderThumb;
+ }
private:
explicit AXSliderThumb(AXObjectCacheImpl&);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
index a72f3e7e174..4f30248e597 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
namespace blink {
@@ -96,7 +96,11 @@ class ObjectVectorAttributeSetter : public AXSparseAttributeSetter {
for (const auto& id : ids) {
if (Element* id_element = scope.getElementById(AtomicString(id))) {
AXObject* ax_id_element = obj.AXObjectCache().GetOrCreate(id_element);
- if (ax_id_element && !ax_id_element->AccessibilityIsIgnored())
+ if (!ax_id_element)
+ continue;
+ if (AXObject* parent = ax_id_element->ParentObject())
+ parent->UpdateChildrenIfNecessary();
+ if (!ax_id_element->AccessibilityIsIgnored())
objects.push_back(ax_id_element);
}
}
@@ -222,7 +226,7 @@ void AXSparseAttributeAOMPropertyClient::AddRelationListProperty(
}
HeapVector<Member<AXObject>> objects;
- for (size_t i = 0; i < relations.length(); ++i) {
+ for (unsigned i = 0; i < relations.length(); ++i) {
AccessibleNode* accessible_node = relations.item(i);
if (accessible_node) {
Element* element = accessible_node->element();
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.cc
index 084a6f6d31d..db5d34482cb 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.cc
@@ -63,10 +63,10 @@ AXObject* AXSVGRoot::ComputeParent() const {
}
// SVG AAM 1.0 S8.2: the default role for an SVG root is "group".
-AccessibilityRole AXSVGRoot::DetermineAccessibilityRole() {
- AccessibilityRole role = AXLayoutObject::DetermineAccessibilityRole();
- if (role == kUnknownRole)
- role = kGroupRole;
+ax::mojom::Role AXSVGRoot::DetermineAccessibilityRole() {
+ ax::mojom::Role role = AXLayoutObject::DetermineAccessibilityRole();
+ if (role == ax::mojom::Role::kUnknown)
+ role = ax::mojom::Role::kGroup;
return role;
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.h
index bd7b586189d..1427cb631f7 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_svg_root.h
@@ -46,7 +46,7 @@ class AXSVGRoot final : public AXLayoutObject {
void SetParent(AXObject*) override;
- AccessibilityRole DetermineAccessibilityRole() override;
+ ax::mojom::Role DetermineAccessibilityRole() override;
bool ComputeAccessibilityIsIgnored(IgnoredReasons*) const override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
index c4dfefe29d6..7719f9641e4 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
@@ -35,7 +35,7 @@ void AXVirtualObject::AddChildren() {
void AXVirtualObject::ChildrenChanged() {
ClearChildren();
- AXObjectCache().PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
+ AXObjectCache().PostNotification(this, ax::mojom::Event::kChildrenChanged);
}
const AtomicString& AXVirtualObject::GetAOMPropertyOrARIAAttribute(
@@ -63,7 +63,7 @@ AccessibleNode* AXVirtualObject::GetAccessibleNode() const {
String AXVirtualObject::TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom& name_from,
+ ax::mojom::NameFrom& name_from,
AXRelatedObjectVector* related_objects,
NameSources* name_sources) const {
if (!accessible_node_)
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
index 666f7dbfca0..c571d96f34b 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
@@ -33,7 +33,7 @@ class MODULES_EXPORT AXVirtualObject : public AXObject {
String TextAlternative(bool recursive,
bool in_aria_labelled_by_traversal,
AXObjectSet& visited,
- AXNameFrom&,
+ ax::mojom::NameFrom&,
AXRelatedObjectVector*,
NameSources*) const override;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
index 33993771b77..55321ce8943 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc
@@ -12,14 +12,16 @@
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/node_list.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
+#include "third_party/blink/renderer/core/inspector/inspected_frames.h"
#include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_style_sheet.h"
-#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
namespace blink {
@@ -40,37 +42,37 @@ namespace {
static const AXID kIDForInspectedNodeWithNoAXNode = 0;
-void AddHasPopupProperty(AXHasPopup has_popup,
+void AddHasPopupProperty(ax::mojom::HasPopup has_popup,
protocol::Array<AXProperty>& properties) {
switch (has_popup) {
- case kAXHasPopupFalse:
+ case ax::mojom::HasPopup::kFalse:
break;
- case kAXHasPopupTrue:
+ case ax::mojom::HasPopup::kTrue:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("true", AXValueTypeEnum::Token)));
break;
- case kAXHasPopupMenu:
+ case ax::mojom::HasPopup::kMenu:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("menu", AXValueTypeEnum::Token)));
break;
- case kAXHasPopupListbox:
+ case ax::mojom::HasPopup::kListbox:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("listbox", AXValueTypeEnum::Token)));
break;
- case kAXHasPopupTree:
+ case ax::mojom::HasPopup::kTree:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("tree", AXValueTypeEnum::Token)));
break;
- case kAXHasPopupGrid:
+ case ax::mojom::HasPopup::kGrid:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("grid", AXValueTypeEnum::Token)));
break;
- case kAXHasPopupDialog:
+ case ax::mojom::HasPopup::kDialog:
properties.addItem(
CreateProperty(AXPropertyNameEnum::HasPopup,
CreateValue("dialog", AXValueTypeEnum::Token)));
@@ -119,26 +121,26 @@ void FillGlobalStates(AXObject& ax_object,
AddHasPopupProperty(ax_object.HasPopup(), properties);
- InvalidState invalid_state = ax_object.GetInvalidState();
+ ax::mojom::InvalidState invalid_state = ax_object.GetInvalidState();
switch (invalid_state) {
- case kInvalidStateUndefined:
+ case ax::mojom::InvalidState::kNone:
break;
- case kInvalidStateFalse:
+ case ax::mojom::InvalidState::kFalse:
properties.addItem(
CreateProperty(AXPropertyNameEnum::Invalid,
CreateValue("false", AXValueTypeEnum::Token)));
break;
- case kInvalidStateTrue:
+ case ax::mojom::InvalidState::kTrue:
properties.addItem(
CreateProperty(AXPropertyNameEnum::Invalid,
CreateValue("true", AXValueTypeEnum::Token)));
break;
- case kInvalidStateSpelling:
+ case ax::mojom::InvalidState::kSpelling:
properties.addItem(
CreateProperty(AXPropertyNameEnum::Invalid,
CreateValue("spelling", AXValueTypeEnum::Token)));
break;
- case kInvalidStateGrammar:
+ case ax::mojom::InvalidState::kGrammar:
properties.addItem(
CreateProperty(AXPropertyNameEnum::Invalid,
CreateValue("grammar", AXValueTypeEnum::Token)));
@@ -153,41 +155,52 @@ void FillGlobalStates(AXObject& ax_object,
}
}
-bool RoleAllowsModal(AccessibilityRole role) {
- return role == kDialogRole || role == kAlertDialogRole;
+bool RoleAllowsModal(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kDialog ||
+ role == ax::mojom::Role::kAlertDialog;
}
-bool RoleAllowsMultiselectable(AccessibilityRole role) {
- return role == kGridRole || role == kListBoxRole || role == kTabListRole ||
- role == kTreeGridRole || role == kTreeRole;
+bool RoleAllowsMultiselectable(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kGrid || role == ax::mojom::Role::kListBox ||
+ role == ax::mojom::Role::kTabList ||
+ role == ax::mojom::Role::kTreeGrid || role == ax::mojom::Role::kTree;
}
-bool RoleAllowsOrientation(AccessibilityRole role) {
- return role == kScrollBarRole || role == kSplitterRole || role == kSliderRole;
+bool RoleAllowsOrientation(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kScrollBar ||
+ role == ax::mojom::Role::kSplitter || role == ax::mojom::Role::kSlider;
}
-bool RoleAllowsReadonly(AccessibilityRole role) {
- return role == kGridRole || role == kCellRole || role == kTextFieldRole ||
- role == kColumnHeaderRole || role == kRowHeaderRole ||
- role == kTreeGridRole;
+bool RoleAllowsReadonly(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kGrid || role == ax::mojom::Role::kCell ||
+ role == ax::mojom::Role::kTextField ||
+ role == ax::mojom::Role::kColumnHeader ||
+ role == ax::mojom::Role::kRowHeader ||
+ role == ax::mojom::Role::kTreeGrid;
}
-bool RoleAllowsRequired(AccessibilityRole role) {
- return role == kComboBoxGroupingRole || role == kComboBoxMenuButtonRole ||
- role == kCellRole || role == kListBoxRole || role == kRadioGroupRole ||
- role == kSpinButtonRole || role == kTextFieldRole ||
- role == kTextFieldWithComboBoxRole || role == kTreeRole ||
- role == kColumnHeaderRole || role == kRowHeaderRole ||
- role == kTreeGridRole;
+bool RoleAllowsRequired(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kComboBoxGrouping ||
+ role == ax::mojom::Role::kComboBoxMenuButton ||
+ role == ax::mojom::Role::kCell || role == ax::mojom::Role::kListBox ||
+ role == ax::mojom::Role::kRadioGroup ||
+ role == ax::mojom::Role::kSpinButton ||
+ role == ax::mojom::Role::kTextField ||
+ role == ax::mojom::Role::kTextFieldWithComboBox ||
+ role == ax::mojom::Role::kTree ||
+ role == ax::mojom::Role::kColumnHeader ||
+ role == ax::mojom::Role::kRowHeader ||
+ role == ax::mojom::Role::kTreeGrid;
}
-bool RoleAllowsSort(AccessibilityRole role) {
- return role == kColumnHeaderRole || role == kRowHeaderRole;
+bool RoleAllowsSort(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kColumnHeader ||
+ role == ax::mojom::Role::kRowHeader;
}
void FillWidgetProperties(AXObject& ax_object,
protocol::Array<AXProperty>& properties) {
- AccessibilityRole role = ax_object.RoleValue();
+ ax::mojom::Role role = ax_object.RoleValue();
String autocomplete = ax_object.AriaAutoComplete();
if (!autocomplete.IsEmpty())
properties.addItem(
@@ -232,7 +245,7 @@ void FillWidgetProperties(AXObject& ax_object,
}
}
- if (role == kTextFieldRole) {
+ if (role == ax::mojom::Role::kTextField) {
properties.addItem(
CreateProperty(AXPropertyNameEnum::Multiline,
CreateBooleanValue(ax_object.IsMultiline())));
@@ -275,23 +288,23 @@ void FillWidgetProperties(AXObject& ax_object,
void FillWidgetStates(AXObject& ax_object,
protocol::Array<AXProperty>& properties) {
- AccessibilityRole role = ax_object.RoleValue();
+ ax::mojom::Role role = ax_object.RoleValue();
const char* checked_prop_val = nullptr;
switch (ax_object.CheckedState()) {
- case kCheckedStateTrue:
+ case ax::mojom::CheckedState::kTrue:
checked_prop_val = "true";
break;
- case kCheckedStateMixed:
+ case ax::mojom::CheckedState::kMixed:
checked_prop_val = "mixed";
break;
- case kCheckedStateFalse:
+ case ax::mojom::CheckedState::kFalse:
checked_prop_val = "false";
break;
- case kCheckedStateUndefined:
+ case ax::mojom::CheckedState::kNone:
break;
}
if (checked_prop_val) {
- auto* const checked_prop_name = role == kToggleButtonRole
+ auto* const checked_prop_name = role == ax::mojom::Role::kToggleButton
? AXPropertyNameEnum::Pressed
: AXPropertyNameEnum::Checked;
properties.addItem(CreateProperty(
@@ -450,7 +463,7 @@ void FillRelationships(AXObject& ax_object,
results.clear();
}
-std::unique_ptr<AXValue> CreateRoleNameValue(AccessibilityRole role) {
+std::unique_ptr<AXValue> CreateRoleNameValue(ax::mojom::Role role) {
AtomicString role_name = AXObject::RoleName(role);
std::unique_ptr<AXValue> role_name_value;
if (!role_name.IsNull()) {
@@ -465,9 +478,9 @@ std::unique_ptr<AXValue> CreateRoleNameValue(AccessibilityRole role) {
} // namespace
InspectorAccessibilityAgent::InspectorAccessibilityAgent(
- Page* page,
+ InspectedFrames* inspected_frames,
InspectorDOMAgent* dom_agent)
- : page_(page), dom_agent_(dom_agent) {}
+ : inspected_frames_(inspected_frames), dom_agent_(dom_agent) {}
Response InspectorAccessibilityAgent::getPartialAXTree(
Maybe<int> dom_node_id,
@@ -545,7 +558,7 @@ std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildObjectForIgnoredNode(
.setNodeId(String::Number(ax_id))
.setIgnored(true)
.build();
- AccessibilityRole role = AccessibilityRole::kIgnoredRole;
+ ax::mojom::Role role = ax::mojom::Role::kIgnored;
ignored_node_object->setRole(CreateRoleNameValue(role));
if (ax_object && ax_object->IsAXLayoutObject()) {
@@ -562,13 +575,15 @@ std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildObjectForIgnoredNode(
ignored_reasons.push_back(IgnoredReason(kAXNotRendered));
}
- if (dom_node)
- ignored_node_object->setBackendDOMNodeId(DOMNodeIds::IdForNode(dom_node));
+ if (dom_node) {
+ ignored_node_object->setBackendDOMNodeId(
+ IdentifiersFactory::IntIdForNode(dom_node));
+ }
std::unique_ptr<protocol::Array<AXProperty>> ignored_reason_properties =
protocol::Array<AXProperty>::create();
- for (size_t i = 0; i < ignored_reasons.size(); i++)
- ignored_reason_properties->addItem(CreateProperty(ignored_reasons[i]));
+ for (IgnoredReason& reason : ignored_reasons)
+ ignored_reason_properties->addItem(CreateProperty(reason));
ignored_node_object->setIgnoredReasons(std::move(ignored_reason_properties));
return ignored_node_object;
@@ -619,7 +634,7 @@ std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildProtocolAXObject(
bool fetch_relatives,
std::unique_ptr<protocol::Array<AXNode>>& nodes,
AXObjectCacheImpl& cache) const {
- AccessibilityRole role = ax_object.RoleValue();
+ ax::mojom::Role role = ax_object.RoleValue();
std::unique_ptr<AXNode> node_object =
AXNode::create()
.setNodeId(String::Number(ax_object.AXObjectID()))
@@ -646,8 +661,7 @@ std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildProtocolAXObject(
if (!name_sources.IsEmpty()) {
std::unique_ptr<protocol::Array<AXValueSource>> name_source_properties =
protocol::Array<AXValueSource>::create();
- for (size_t i = 0; i < name_sources.size(); ++i) {
- NameSource& name_source = name_sources[i];
+ for (NameSource& name_source : name_sources) {
name_source_properties->addItem(CreateValueSource(name_source));
if (name_source.text.IsNull() || name_source.superseded)
continue;
@@ -669,6 +683,37 @@ std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildProtocolAXObject(
return node_object;
}
+Response InspectorAccessibilityAgent::getFullAXTree(
+ std::unique_ptr<protocol::Array<AXNode>>* nodes) {
+ Document* document = inspected_frames_->Root()->GetDocument();
+ if (!document)
+ return Response::Error("No document.");
+ *nodes = protocol::Array<protocol::Accessibility::AXNode>::create();
+ AXContext ax_context(*document);
+ AXObjectCacheImpl& cache = ToAXObjectCacheImpl(ax_context.GetAXObjectCache());
+ Deque<AXID> ids;
+ ids.push_back(cache.Root()->AXObjectID());
+ while (!ids.empty()) {
+ AXID ax_id = ids.front();
+ ids.pop_front();
+ AXObject* ax_object = cache.ObjectFromAXID(ax_id);
+ std::unique_ptr<AXNode> node =
+ BuildProtocolAXObject(*ax_object, nullptr, false, *nodes, cache);
+
+ std::unique_ptr<protocol::Array<AXNodeId>> child_ids =
+ protocol::Array<AXNodeId>::create();
+ const AXObject::AXObjectVector& children = ax_object->Children();
+ for (unsigned i = 0; i < children.size(); i++) {
+ AXObject& child_ax_object = *children[i].Get();
+ child_ids->addItem(String::Number(child_ax_object.AXObjectID()));
+ ids.push_back(child_ax_object.AXObjectID());
+ }
+ node->setChildIds(std::move(child_ids));
+ (*nodes)->addItem(std::move(node));
+ }
+ return Response::OK();
+}
+
void InspectorAccessibilityAgent::FillCoreProperties(
AXObject& ax_object,
AXObject* inspected_ax_object,
@@ -676,11 +721,11 @@ void InspectorAccessibilityAgent::FillCoreProperties(
AXNode& node_object,
std::unique_ptr<protocol::Array<AXNode>>& nodes,
AXObjectCacheImpl& cache) const {
- AXNameFrom name_from;
+ ax::mojom::NameFrom name_from;
AXObject::AXObjectVector name_objects;
ax_object.GetName(name_from, &name_objects);
- AXDescriptionFrom description_from;
+ ax::mojom::DescriptionFrom description_from;
AXObject::AXObjectVector description_objects;
String description =
ax_object.Description(name_from, description_from, &description_objects);
@@ -705,7 +750,7 @@ void InspectorAccessibilityAgent::FillCoreProperties(
Node* node = ax_object.GetNode();
if (node)
- node_object.setBackendDOMNodeId(DOMNodeIds::IdForNode(node));
+ node_object.setBackendDOMNodeId(IdentifiersFactory::IntIdForNode(node));
}
void InspectorAccessibilityAgent::PopulateRelatives(
@@ -764,7 +809,7 @@ void InspectorAccessibilityAgent::AddChildren(
}
void InspectorAccessibilityAgent::Trace(blink::Visitor* visitor) {
- visitor->Trace(page_);
+ visitor->Trace(inspected_frames_);
visitor->Trace(dom_agent_);
InspectorBaseAgent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
index 497df05f9b8..c28a394523d 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h
@@ -15,7 +15,7 @@ namespace blink {
class AXObject;
class AXObjectCacheImpl;
class InspectorDOMAgent;
-class Page;
+class InspectedFrames;
using protocol::Accessibility::AXNode;
using protocol::Accessibility::AXNodeId;
@@ -23,7 +23,7 @@ using protocol::Accessibility::AXNodeId;
class MODULES_EXPORT InspectorAccessibilityAgent
: public InspectorBaseAgent<protocol::Accessibility::Metainfo> {
public:
- InspectorAccessibilityAgent(Page*, InspectorDOMAgent*);
+ InspectorAccessibilityAgent(InspectedFrames*, InspectorDOMAgent*);
// Base agent methods.
void Trace(blink::Visitor*) override;
@@ -36,6 +36,9 @@ class MODULES_EXPORT InspectorAccessibilityAgent
protocol::Maybe<bool> fetch_relatives,
std::unique_ptr<protocol::Array<protocol::Accessibility::AXNode>>*)
override;
+ protocol::Response getFullAXTree(
+ std::unique_ptr<protocol::Array<protocol::Accessibility::AXNode>>*)
+ override;
private:
std::unique_ptr<AXNode> BuildObjectForIgnoredNode(
@@ -86,7 +89,7 @@ class MODULES_EXPORT InspectorAccessibilityAgent
std::unique_ptr<protocol::Array<AXNode>>& nodes,
AXObjectCacheImpl&) const;
- Member<Page> page_;
+ Member<InspectedFrames> inspected_frames_;
Member<InspectorDOMAgent> dom_agent_;
DISALLOW_COPY_AND_ASSIGN(InspectorAccessibilityAgent);
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
index fe1fc402dff..91169601a87 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
@@ -46,7 +47,7 @@ String IgnoredReasonName(AXIgnoredReason reason) {
return "notRendered";
case kAXNotVisible:
return "notVisible";
- case kAXPresentationalRole:
+ case kAXPresentational:
return "presentationalRole";
case kAXProbablyPresentational:
return "probablyPresentational";
@@ -102,7 +103,7 @@ std::unique_ptr<AXRelatedNode> RelatedNodeForAXObject(const AXObject& ax_object,
Node* node = ax_object.GetNode();
if (!node)
return nullptr;
- int backend_node_id = DOMNodeIds::IdForNode(node);
+ int backend_node_id = IdentifiersFactory::IntIdForNode(node);
if (!backend_node_id)
return nullptr;
std::unique_ptr<AXRelatedNode> related_node =
@@ -167,19 +168,19 @@ std::unique_ptr<AXValue> CreateRelatedNodeListValue(
.build();
}
-String ValueSourceType(AXNameFrom name_from) {
+String ValueSourceType(ax::mojom::NameFrom name_from) {
switch (name_from) {
- case kAXNameFromAttribute:
- case kAXNameFromAttributeExplicitlyEmpty:
- case kAXNameFromTitle:
- case kAXNameFromValue:
+ case ax::mojom::NameFrom::kAttribute:
+ case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
+ case ax::mojom::NameFrom::kTitle:
+ case ax::mojom::NameFrom::kValue:
return AXValueSourceTypeEnum::Attribute;
- case kAXNameFromContents:
+ case ax::mojom::NameFrom::kContents:
return AXValueSourceTypeEnum::Contents;
- case kAXNameFromPlaceholder:
+ case ax::mojom::NameFrom::kPlaceholder:
return AXValueSourceTypeEnum::Placeholder;
- case kAXNameFromCaption:
- case kAXNameFromRelatedElement:
+ case ax::mojom::NameFrom::kCaption:
+ case ax::mojom::NameFrom::kRelatedElement:
return AXValueSourceTypeEnum::RelatedElement;
default:
return AXValueSourceTypeEnum::Implicit; // TODO(aboxhall): what to do
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn b/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
index 54193864a31..ddde73a9135 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
@@ -12,8 +12,8 @@ blink_modules_sources("animationworklet") {
"animation_worklet_global_scope.h",
"animation_worklet_messaging_proxy.cc",
"animation_worklet_messaging_proxy.h",
- "animation_worklet_proxy_client_impl.cc",
- "animation_worklet_proxy_client_impl.h",
+ "animation_worklet_proxy_client.cc",
+ "animation_worklet_proxy_client.h",
"animation_worklet_thread.cc",
"animation_worklet_thread.h",
"animator.cc",
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
index cea538e58ea..2722b7d0e25 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
@@ -6,12 +6,11 @@
#include "base/atomic_sequence_num.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h"
-#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h"
base::AtomicSequenceNumber g_next_worklet_id;
@@ -39,9 +38,9 @@ WorkletGlobalScopeProxy* AnimationWorklet::CreateGlobalScope() {
DCHECK(NeedsToCreateGlobalScope());
AnimationWorkletThread::EnsureSharedBackingThread();
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
AnimationWorkletProxyClient* proxy_client =
- AnimationWorkletProxyClientImpl::FromDocument(document, scope_id_);
+ AnimationWorkletProxyClient::FromDocument(document, scope_id_);
WorkerClients* worker_clients = WorkerClients::Create();
ProvideAnimationWorkletProxyClientTo(worker_clients, proxy_client);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
index fa07268915d..5cd1e179f90 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/workers/worklet.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_animators_state.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutators_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
index e559ac300fa..c7912c97333 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -7,8 +7,9 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_parser.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
+#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/animationworklet/worklet_animation_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
@@ -23,9 +24,9 @@ void UpdateAnimation(Animator* animator,
ScriptState* script_state,
WorkletAnimationId id,
double current_time,
- CompositorMutatorOutputState* result) {
- CompositorMutatorOutputState::AnimationState animation_output(id,
- base::nullopt);
+ AnimationWorkletDispatcherOutput* result) {
+ AnimationWorkletDispatcherOutput::AnimationState animation_output(
+ id, base::nullopt);
if (animator->Animate(script_state, current_time, &animation_output)) {
result->animations.push_back(std::move(animation_output));
}
@@ -35,25 +36,23 @@ void UpdateAnimation(Animator* animator,
AnimationWorkletGlobalScope* AnimationWorkletGlobalScope::Create(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
- v8::Isolate* isolate,
WorkerThread* thread) {
- return new AnimationWorkletGlobalScope(std::move(creation_params), isolate,
- thread);
+ return new AnimationWorkletGlobalScope(std::move(creation_params), thread);
}
AnimationWorkletGlobalScope::AnimationWorkletGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
- v8::Isolate* isolate,
WorkerThread* thread)
- : ThreadedWorkletGlobalScope(std::move(creation_params), isolate, thread) {
-}
+ : WorkletGlobalScope(std::move(creation_params),
+ thread->GetWorkerReportingProxy(),
+ thread) {}
AnimationWorkletGlobalScope::~AnimationWorkletGlobalScope() = default;
void AnimationWorkletGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(animator_definitions_);
visitor->Trace(animators_);
- ThreadedWorkletGlobalScope::Trace(visitor);
+ WorkletGlobalScope::Trace(visitor);
}
void AnimationWorkletGlobalScope::Dispose() {
@@ -61,7 +60,7 @@ void AnimationWorkletGlobalScope::Dispose() {
if (AnimationWorkletProxyClient* proxy_client =
AnimationWorkletProxyClient::From(Clients()))
proxy_client->Dispose();
- ThreadedWorkletGlobalScope::Dispose();
+ WorkletGlobalScope::Dispose();
}
Animator* AnimationWorkletGlobalScope::CreateAnimatorFor(
@@ -119,6 +118,15 @@ std::unique_ptr<AnimationWorkletOutput> AnimationWorkletGlobalScope::Mutate(
animation.current_time, result.get());
}
+ for (const auto& worklet_animation_id : mutator_input.peeked_animations) {
+ int id = worklet_animation_id.animation_id;
+ Animator* animator = animators_.at(id);
+
+ result->animations.emplace_back(
+ worklet_animation_id,
+ animator ? animator->GetLastLocalTime() : base::nullopt);
+ }
+
return result;
}
@@ -190,9 +198,11 @@ Animator* AnimationWorkletGlobalScope::CreateInstance(
if (options && options->GetData())
value = options->GetData()->Deserialize(isolate);
- v8::Local<v8::Object> instance;
- if (!V8ObjectConstructor::NewInstance(isolate, constructor,
- !value.IsEmpty() ? 1 : 0, &value)
+ v8::Local<v8::Value> instance;
+ if (!V8ScriptRunner::CallAsConstructor(
+ isolate, constructor,
+ ExecutionContext::From(ScriptController()->GetScriptState()),
+ !value.IsEmpty() ? 1 : 0, &value)
.ToLocal(&instance))
return nullptr;
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
index cfcb8da7720..c0ee79bc731 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
@@ -6,12 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_GLOBAL_SCOPE_H_
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
-#include "third_party/blink/renderer/core/workers/threaded_worklet_global_scope.h"
+#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/modules/animationworklet/animator.h"
#include "third_party/blink/renderer/modules/animationworklet/animator_definition.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_animators_state.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutators_state.h"
namespace blink {
@@ -27,14 +27,12 @@ class WorkletAnimationOptions;
// The scope keeps a map of these animator definitions and can look them up
// based on their name. The scope also owns a list of active animators that it
// animates.
-class MODULES_EXPORT AnimationWorkletGlobalScope
- : public ThreadedWorkletGlobalScope {
+class MODULES_EXPORT AnimationWorkletGlobalScope : public WorkletGlobalScope {
DEFINE_WRAPPERTYPEINFO();
public:
static AnimationWorkletGlobalScope* Create(
std::unique_ptr<GlobalScopeCreationParams>,
- v8::Isolate*,
WorkerThread*);
~AnimationWorkletGlobalScope() override;
void Trace(blink::Visitor*) override;
@@ -54,7 +52,6 @@ class MODULES_EXPORT AnimationWorkletGlobalScope
private:
AnimationWorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
- v8::Isolate*,
WorkerThread*);
void RegisterWithProxyClientIfNeeded();
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
index 04887c17559..1b5aea328ee 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/script/script.h"
@@ -21,6 +20,7 @@
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h"
#include "third_party/blink/renderer/modules/animationworklet/animator.h"
#include "third_party/blink/renderer/modules/animationworklet/animator_definition.h"
@@ -36,17 +36,14 @@
namespace blink {
namespace {
-class MockAnimationWorkletProxyClient
- : public GarbageCollected<MockAnimationWorkletProxyClient>,
- public AnimationWorkletProxyClient {
- USING_GARBAGE_COLLECTED_MIXIN(MockAnimationWorkletProxyClient);
-
+class MockAnimationWorkletProxyClient : public AnimationWorkletProxyClient {
public:
- MockAnimationWorkletProxyClient() : did_set_global_scope_(false) {}
+ MockAnimationWorkletProxyClient()
+ : AnimationWorkletProxyClient(0, nullptr, nullptr, nullptr, nullptr),
+ did_set_global_scope_(false) {}
void SetGlobalScope(WorkletGlobalScope*) override {
did_set_global_scope_ = true;
}
- void Dispose() override {}
bool did_set_global_scope() { return did_set_global_scope_; }
private:
@@ -60,7 +57,7 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
AnimationWorkletGlobalScopeTest() = default;
void SetUp() override {
- AnimationWorkletThread::CreateSharedBackingThreadForTest();
+ AnimationWorkletThread::EnsureSharedBackingThread();
PageTestBase::SetUp(IntSize());
Document* document = &GetDocument();
document->SetURL(KURL("https://example.com/"));
@@ -262,13 +259,14 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
ScriptState::Scope scope(script_state);
global_scope->ScriptController()->Evaluate(ScriptSourceCode(
- R"JS(
+ R"JS(
registerAnimator('test', class {
animate (currentTime, effect) {
effect.localTime = 123;
}
});
- )JS"));
+ )JS"),
+ kSharableCrossOrigin);
// Passing a new input state with a new animation id should cause the
// worklet to create and animate an animator.
@@ -307,13 +305,14 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
ScriptState::Scope scope(script_state);
global_scope->ScriptController()->Evaluate(ScriptSourceCode(
- R"JS(
+ R"JS(
registerAnimator('test', class {
animate (currentTime, effect) {
effect.localTime = 123;
}
});
- )JS"));
+ )JS"),
+ kSharableCrossOrigin);
cc::WorkletAnimationId animation_id = {1, 1};
AnimationWorkletInput state;
@@ -355,13 +354,14 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
ScriptState::Scope scope(script_state);
global_scope->ScriptController()->Evaluate(ScriptSourceCode(
- R"JS(
+ R"JS(
registerAnimator('test', class {
animate (currentTime, effect) {
effect.localTime = 123;
}
});
- )JS"));
+ )JS"),
+ kSharableCrossOrigin);
cc::WorkletAnimationId animation_id = {1, 1};
AnimationWorkletInput state;
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
index a58f2c46ce0..a13f3627e5b 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_MESSAGING_PROXY_H_
#include <memory>
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc
new file mode 100644
index 00000000000..2c9082e2901
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc
@@ -0,0 +1,149 @@
+// 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 "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
+
+#include "third_party/blink/renderer/core/animation/worklet_animation_controller.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.h"
+
+namespace blink {
+
+const char AnimationWorkletProxyClient::kSupplementName[] =
+ "AnimationWorkletProxyClient";
+
+AnimationWorkletProxyClient::AnimationWorkletProxyClient(
+ int scope_id,
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
+ compositor_mutator_dispatcher,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_mutator_runner,
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
+ main_thread_mutator_dispatcher,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_mutator_runner)
+ : scope_id_(scope_id), state_(RunState::kUninitialized) {
+ DCHECK(IsMainThread());
+ mutator_items_.emplace_back(std::move(compositor_mutator_dispatcher),
+ std::move(compositor_mutator_runner));
+ mutator_items_.emplace_back(std::move(main_thread_mutator_dispatcher),
+ std::move(main_thread_mutator_runner));
+}
+
+void AnimationWorkletProxyClient::Trace(blink::Visitor* visitor) {
+ Supplement<WorkerClients>::Trace(visitor);
+ AnimationWorkletMutator::Trace(visitor);
+}
+
+void AnimationWorkletProxyClient::SetGlobalScope(
+ WorkletGlobalScope* global_scope) {
+ DCHECK(global_scope);
+ DCHECK(global_scope->IsContextThread());
+ if (state_ == RunState::kDisposed)
+ return;
+ DCHECK(state_ == RunState::kUninitialized);
+
+ global_scope_ = static_cast<AnimationWorkletGlobalScope*>(global_scope);
+ // TODO(majidvp): Add an AnimationWorklet task type when the spec is final.
+ scoped_refptr<base::SingleThreadTaskRunner> global_scope_runner =
+ global_scope_->GetThread()->GetTaskRunner(TaskType::kMiscPlatformAPI);
+ state_ = RunState::kWorking;
+
+ for (auto& mutator_item : mutator_items_) {
+ DCHECK(mutator_item.mutator_runner);
+ PostCrossThreadTask(
+ *mutator_item.mutator_runner, FROM_HERE,
+ CrossThreadBind(&AnimationWorkletMutatorDispatcherImpl::
+ RegisterAnimationWorkletMutator,
+ mutator_item.mutator_dispatcher,
+ WrapCrossThreadPersistent(this), global_scope_runner));
+ }
+}
+
+void AnimationWorkletProxyClient::Dispose() {
+ if (state_ == RunState::kWorking) {
+ // At worklet scope termination break the reference to the clients if it is
+ // still alive.
+ for (auto& mutator_item : mutator_items_) {
+ DCHECK(mutator_item.mutator_runner);
+ PostCrossThreadTask(
+ *mutator_item.mutator_runner, FROM_HERE,
+ CrossThreadBind(&AnimationWorkletMutatorDispatcherImpl::
+ UnregisterAnimationWorkletMutator,
+ mutator_item.mutator_dispatcher,
+ WrapCrossThreadPersistent(this)));
+ }
+
+ DCHECK(global_scope_);
+ DCHECK(global_scope_->IsContextThread());
+
+ // At worklet scope termination break the reference cycle between
+ // AnimationWorkletGlobalScope and AnimationWorkletProxyClient.
+ global_scope_ = nullptr;
+ }
+
+ mutator_items_.clear();
+
+ DCHECK(state_ != RunState::kDisposed);
+ state_ = RunState::kDisposed;
+}
+
+std::unique_ptr<AnimationWorkletOutput> AnimationWorkletProxyClient::Mutate(
+ std::unique_ptr<AnimationWorkletInput> input) {
+ DCHECK(input);
+#if DCHECK_IS_ON()
+ DCHECK(input->ValidateScope(scope_id_))
+ << "Input has state that does not belong to this global scope: "
+ << scope_id_;
+#endif
+
+ if (!global_scope_)
+ return nullptr;
+
+ auto output = global_scope_->Mutate(*input);
+
+ // TODO(petermayo): https://crbug.com/791280 PostCrossThreadTask to supply
+ // this rather than return it.
+ return output;
+}
+
+// static
+AnimationWorkletProxyClient* AnimationWorkletProxyClient::FromDocument(
+ Document* document,
+ int scope_id) {
+ WebLocalFrameImpl* local_frame =
+ WebLocalFrameImpl::FromFrame(document->GetFrame());
+
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_host_queue;
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
+ compositor_mutator_dispatcher =
+ local_frame->LocalRootFrameWidget()
+ ->EnsureCompositorMutatorDispatcher(&compositor_host_queue);
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_host_queue;
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
+ main_thread_mutator_dispatcher =
+ document->GetWorkletAnimationController()
+ .EnsureMainThreadMutatorDispatcher(&main_thread_host_queue);
+
+ return new AnimationWorkletProxyClient(
+ scope_id, std::move(compositor_mutator_dispatcher),
+ std::move(compositor_host_queue),
+ std::move(main_thread_mutator_dispatcher),
+ std::move(main_thread_host_queue));
+}
+
+AnimationWorkletProxyClient* AnimationWorkletProxyClient::From(
+ WorkerClients* clients) {
+ return Supplement<WorkerClients>::From<AnimationWorkletProxyClient>(clients);
+}
+
+void ProvideAnimationWorkletProxyClientTo(WorkerClients* clients,
+ AnimationWorkletProxyClient* client) {
+ clients->ProvideSupplement(client);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h
new file mode 100644
index 00000000000..6de77a34940
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h
@@ -0,0 +1,85 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_H_
+
+#include "base/macros.h"
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/core/workers/worker_clients.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h"
+
+namespace blink {
+
+class AnimationWorkletMutatorDispatcherImpl;
+class Document;
+class WorkletGlobalScope;
+
+// Mediates between animation worklet global scope and its associated
+// dispatchers. An AnimationWorkletProxyClient is associated with a single
+// global scope and up to two dispatchers representing main and compositor
+// threads.
+//
+// This is constructed on the main thread but it is used in the worklet backing
+// thread.
+class MODULES_EXPORT AnimationWorkletProxyClient
+ : public GarbageCollectedFinalized<AnimationWorkletProxyClient>,
+ public Supplement<WorkerClients>,
+ public AnimationWorkletMutator {
+ USING_GARBAGE_COLLECTED_MIXIN(AnimationWorkletProxyClient);
+ DISALLOW_COPY_AND_ASSIGN(AnimationWorkletProxyClient);
+
+ public:
+ static const char kSupplementName[];
+
+ // This client is hooked to the given |mutatee|, on the given
+ // |mutatee_runner|.
+ explicit AnimationWorkletProxyClient(
+ int scope_id,
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> compositor_mutatee,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_mutatee_runner,
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> main_thread_mutatee,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_mutatee_runner);
+ void Trace(blink::Visitor*) override;
+
+ virtual void SetGlobalScope(WorkletGlobalScope*);
+ void Dispose();
+
+ // AnimationWorkletMutator:
+ // These methods are invoked on the animation worklet thread.
+ int GetScopeId() const override { return scope_id_; }
+ std::unique_ptr<AnimationWorkletOutput> Mutate(
+ std::unique_ptr<AnimationWorkletInput> input) override;
+
+ static AnimationWorkletProxyClient* FromDocument(Document*, int scope_id);
+ static AnimationWorkletProxyClient* From(WorkerClients*);
+
+ private:
+ const int scope_id_;
+
+ struct MutatorItem {
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> mutator_dispatcher;
+ scoped_refptr<base::SingleThreadTaskRunner> mutator_runner;
+ MutatorItem(
+ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> mutator_dispatcher,
+ scoped_refptr<base::SingleThreadTaskRunner> mutator_runner)
+ : mutator_dispatcher(std::move(mutator_dispatcher)),
+ mutator_runner(std::move(mutator_runner)) {}
+ };
+ WTF::Vector<MutatorItem> mutator_items_;
+
+ CrossThreadPersistent<AnimationWorkletGlobalScope> global_scope_;
+
+ enum RunState { kUninitialized, kWorking, kDisposed } state_;
+};
+
+void MODULES_EXPORT
+ProvideAnimationWorkletProxyClientTo(WorkerClients*,
+ AnimationWorkletProxyClient*);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.cc
deleted file mode 100644
index 61db57bb25d..00000000000
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h"
-
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
-#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
-#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h"
-
-namespace blink {
-
-AnimationWorkletProxyClientImpl::AnimationWorkletProxyClientImpl(
- int scope_id,
- base::WeakPtr<CompositorMutatorImpl> mutator,
- scoped_refptr<base::SingleThreadTaskRunner> mutator_runner)
- : scope_id_(scope_id),
- mutator_(std::move(mutator)),
- mutator_runner_(std::move(mutator_runner)),
- state_(RunState::kUninitialized) {
- DCHECK(IsMainThread());
-}
-
-void AnimationWorkletProxyClientImpl::Trace(blink::Visitor* visitor) {
- AnimationWorkletProxyClient::Trace(visitor);
- CompositorAnimator::Trace(visitor);
-}
-
-void AnimationWorkletProxyClientImpl::SetGlobalScope(
- WorkletGlobalScope* global_scope) {
- DCHECK(global_scope);
- DCHECK(global_scope->IsContextThread());
- if (state_ == RunState::kDisposed)
- return;
- DCHECK(state_ == RunState::kUninitialized);
-
- global_scope_ = static_cast<AnimationWorkletGlobalScope*>(global_scope);
- // TODO(majidvp): Add an AnimationWorklet task type when the spec is final.
- scoped_refptr<base::SingleThreadTaskRunner> global_scope_runner =
- global_scope_->GetThread()->GetTaskRunner(TaskType::kMiscPlatformAPI);
- state_ = RunState::kWorking;
- DCHECK(mutator_runner_);
- PostCrossThreadTask(
- *mutator_runner_, FROM_HERE,
- CrossThreadBind(&CompositorMutatorImpl::RegisterCompositorAnimator,
- mutator_, WrapCrossThreadPersistent(this),
- global_scope_runner));
-}
-
-void AnimationWorkletProxyClientImpl::Dispose() {
- if (state_ == RunState::kWorking) {
- // At worklet scope termination break the reference to the Client from
- // the compositor if it is still alive.
- DCHECK(mutator_runner_);
- PostCrossThreadTask(
- *mutator_runner_, FROM_HERE,
- CrossThreadBind(&CompositorMutatorImpl::UnregisterCompositorAnimator,
- mutator_, WrapCrossThreadPersistent(this)));
-
- DCHECK(global_scope_);
- DCHECK(global_scope_->IsContextThread());
-
- // At worklet scope termination break the reference cycle between
- // AnimationWorkletGlobalScope and AnimationWorkletProxyClientImpl.
- global_scope_ = nullptr;
- }
-
- mutator_runner_ = nullptr;
- DCHECK(state_ != RunState::kDisposed);
- state_ = RunState::kDisposed;
-}
-
-std::unique_ptr<AnimationWorkletOutput> AnimationWorkletProxyClientImpl::Mutate(
- std::unique_ptr<AnimationWorkletInput> input) {
- DCHECK(input);
-#if DCHECK_IS_ON()
- DCHECK(input->ValidateScope(scope_id_))
- << "Input has state that does not belong to this global scope: "
- << scope_id_;
-#endif
-
- if (!global_scope_)
- return nullptr;
-
- auto output = global_scope_->Mutate(*input);
-
- // TODO(petermayo): https://crbug.com/791280 PostCrossThreadTask to supply
- // this rather than return it.
- return output;
-}
-
-// static
-AnimationWorkletProxyClientImpl* AnimationWorkletProxyClientImpl::FromDocument(
- Document* document,
- int scope_id) {
- WebLocalFrameImpl* local_frame =
- WebLocalFrameImpl::FromFrame(document->GetFrame());
- scoped_refptr<base::SingleThreadTaskRunner> mutator_queue;
- base::WeakPtr<CompositorMutatorImpl> mutator =
- local_frame->LocalRootFrameWidget()->EnsureCompositorMutator(
- &mutator_queue);
- return new AnimationWorkletProxyClientImpl(scope_id, std::move(mutator),
- std::move(mutator_queue));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h
deleted file mode 100644
index a63b30eb3ed..00000000000
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_impl.h
+++ /dev/null
@@ -1,67 +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 THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_IMPL_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_IMPL_H_
-
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
-#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_animator.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
-
-namespace blink {
-
-class CompositorMutatorImpl;
-class Document;
-class WorkletGlobalScope;
-
-// Mediates between one Animator and the associated CompositorMutatorImpl. There
-// is one AnimationWorkletProxyClientImpl per Animator but there may be multiple
-// for a given mutator and animatorWorklet.
-//
-// This is constructed on the main thread but it is used in the worklet backing
-// thread.
-class MODULES_EXPORT AnimationWorkletProxyClientImpl final
- : public GarbageCollectedFinalized<AnimationWorkletProxyClientImpl>,
- public AnimationWorkletProxyClient,
- public CompositorAnimator {
- WTF_MAKE_NONCOPYABLE(AnimationWorkletProxyClientImpl);
- USING_GARBAGE_COLLECTED_MIXIN(AnimationWorkletProxyClientImpl);
-
- public:
- // This client is hooked to the given |mutatee|, on the given
- // |mutatee_runner|.
- explicit AnimationWorkletProxyClientImpl(
- int scope_id,
- base::WeakPtr<CompositorMutatorImpl> mutatee,
- scoped_refptr<base::SingleThreadTaskRunner> mutatee_runner);
- void Trace(blink::Visitor*) override;
-
- // AnimationWorkletProxyClient:
- void SetGlobalScope(WorkletGlobalScope*) override;
- void Dispose() override;
-
- // CompositorAnimator:
- // These methods are invoked on the animation worklet thread.
- int GetScopeId() const override { return scope_id_; }
- std::unique_ptr<AnimationWorkletOutput> Mutate(
- std::unique_ptr<AnimationWorkletInput> input) override;
-
- static AnimationWorkletProxyClientImpl* FromDocument(Document*, int scope_id);
-
- private:
- const int scope_id_;
- base::WeakPtr<CompositorMutatorImpl> mutator_;
- scoped_refptr<base::SingleThreadTaskRunner> mutator_runner_;
-
- CrossThreadPersistent<AnimationWorkletGlobalScope> global_scope_;
-
- enum RunState { kUninitialized, kWorking, kDisposed } state_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATION_WORKLET_PROXY_CLIENT_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
index cd9d5f2ce83..6f0476646ec 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
@@ -31,12 +31,6 @@ AnimationWorkletThread::AnimationWorkletThread(
AnimationWorkletThread::~AnimationWorkletThread() = default;
-WebThread* AnimationWorkletThread::GetSharedBackingThread() {
- auto* instance = WorkletThreadHolder<AnimationWorkletThread>::GetInstance();
- DCHECK(instance);
- return &(instance->GetThread()->BackingThread().PlatformThread());
-}
-
WorkerBackingThread& AnimationWorkletThread::GetWorkerBackingThread() {
return *WorkletThreadHolder<AnimationWorkletThread>::GetInstance()
->GetThread();
@@ -61,24 +55,18 @@ void AnimationWorkletThread::CollectAllGarbage() {
void AnimationWorkletThread::EnsureSharedBackingThread() {
WorkletThreadHolder<AnimationWorkletThread>::EnsureInstance(
- WebThreadCreationParams(WebThreadType::kAnimationWorkletThread));
+ ThreadCreationParams(WebThreadType::kAnimationWorkletThread));
}
void AnimationWorkletThread::ClearSharedBackingThread() {
WorkletThreadHolder<AnimationWorkletThread>::ClearInstance();
}
-void AnimationWorkletThread::CreateSharedBackingThreadForTest() {
- WorkletThreadHolder<AnimationWorkletThread>::CreateForTest(
- WebThreadCreationParams(WebThreadType::kAnimationWorkletThread));
-}
-
WorkerOrWorkletGlobalScope* AnimationWorkletThread::CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("animation-worklet"),
"AnimationWorkletThread::CreateWorkerGlobalScope");
- return AnimationWorkletGlobalScope::Create(std::move(creation_params),
- GetIsolate(), this);
+ return AnimationWorkletGlobalScope::Create(std::move(creation_params), this);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
index 78fe953d9de..622a77127cf 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
@@ -32,13 +32,6 @@ class MODULES_EXPORT AnimationWorkletThread final : public WorkerThread {
static void EnsureSharedBackingThread();
static void ClearSharedBackingThread();
- static void CreateSharedBackingThreadForTest();
-
- // This only can be called after EnsureSharedBackingThread() is performed.
- // Currently AnimationWorkletThread owns only one thread and it is shared
- // by all the customers.
- static WebThread* GetSharedBackingThread();
-
private:
explicit AnimationWorkletThread(WorkerReportingProxy&);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
index c1b6d4aa1ec..e7462ff02ac 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
-#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/script/script.h"
@@ -25,10 +24,10 @@
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
+#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
@@ -37,26 +36,11 @@
namespace blink {
namespace {
-class AnimationWorkletTestPlatform : public TestingPlatformSupport {
+class TestAnimationWorkletProxyClient : public AnimationWorkletProxyClient {
public:
- // Need to override the thread creating support so we can actually run
- // Animation Worklet code that would go on a backing thread in non-test
- // code. i.e. most tests remove the extra threads, but we need this one.
- std::unique_ptr<WebThread> CreateThread(
- const blink::WebThreadCreationParams& params) override {
- return old_platform_->CreateThread(params);
- }
-};
-
-class TestAnimationWorkletProxyClient
- : public GarbageCollected<TestAnimationWorkletProxyClient>,
- public AnimationWorkletProxyClient {
- USING_GARBAGE_COLLECTED_MIXIN(TestAnimationWorkletProxyClient);
-
- public:
- TestAnimationWorkletProxyClient() = default;
+ TestAnimationWorkletProxyClient()
+ : AnimationWorkletProxyClient(0, nullptr, nullptr, nullptr, nullptr){};
void SetGlobalScope(WorkletGlobalScope*) override {}
- void Dispose() override {}
};
} // namespace
@@ -64,7 +48,7 @@ class TestAnimationWorkletProxyClient
class AnimationWorkletThreadTest : public PageTestBase {
public:
void SetUp() override {
- AnimationWorkletThread::CreateSharedBackingThreadForTest();
+ AnimationWorkletThread::EnsureSharedBackingThread();
PageTestBase::SetUp(IntSize());
Document* document = &GetDocument();
document->SetURL(KURL("https://example.com/"));
@@ -131,7 +115,6 @@ class AnimationWorkletThreadTest : public PageTestBase {
}
std::unique_ptr<WorkerReportingProxy> reporting_proxy_;
- ScopedTestingPlatformSupport<AnimationWorkletTestPlatform> platform_;
};
TEST_F(AnimationWorkletThreadTest, Basic) {
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
index 01716224d8d..5faecda350b 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -15,7 +15,7 @@ namespace blink {
Animator::Animator(v8::Isolate* isolate,
AnimatorDefinition* definition,
- v8::Local<v8::Object> instance)
+ v8::Local<v8::Value> instance)
: definition_(definition),
instance_(isolate, instance),
effect_(new EffectProxy()) {}
@@ -25,15 +25,16 @@ Animator::~Animator() = default;
void Animator::Trace(blink::Visitor* visitor) {
visitor->Trace(definition_);
visitor->Trace(effect_);
- visitor->Trace(instance_.Cast<v8::Value>());
+ visitor->Trace(instance_);
}
-bool Animator::Animate(ScriptState* script_state,
- double current_time,
- CompositorMutatorOutputState::AnimationState* output) {
+bool Animator::Animate(
+ ScriptState* script_state,
+ double current_time,
+ AnimationWorkletDispatcherOutput::AnimationState* output) {
v8::Isolate* isolate = script_state->GetIsolate();
- v8::Local<v8::Object> instance = instance_.NewLocal(isolate);
+ v8::Local<v8::Value> instance = instance_.NewLocal(isolate);
v8::Local<v8::Function> animate = definition_->AnimateLocal(isolate);
if (IsUndefinedOrNull(instance) || IsUndefinedOrNull(animate))
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
index d4b302429e5..c37bf14d182 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h
@@ -9,7 +9,7 @@
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_animators_state.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutators_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
#include "v8/include/v8.h"
@@ -25,7 +25,7 @@ class ScriptState;
class Animator final : public GarbageCollectedFinalized<Animator>,
public NameClient {
public:
- Animator(v8::Isolate*, AnimatorDefinition*, v8::Local<v8::Object> instance);
+ Animator(v8::Isolate*, AnimatorDefinition*, v8::Local<v8::Value> instance);
~Animator();
void Trace(blink::Visitor*);
const char* NameInHeapSnapshot() const override { return "Animator"; }
@@ -35,13 +35,16 @@ class Animator final : public GarbageCollectedFinalized<Animator>,
// the output state with new updates.
bool Animate(ScriptState*,
double current_time,
- CompositorMutatorOutputState::AnimationState*);
+ AnimationWorkletDispatcherOutput::AnimationState*);
+ base::Optional<TimeDelta> GetLastLocalTime() const {
+ return effect_->local_time();
+ }
private:
// This object keeps the definition object, and animator instance alive.
// It participates in wrapper tracing as it holds onto V8 wrappers.
TraceWrapperMember<AnimatorDefinition> definition_;
- TraceWrapperV8Reference<v8::Object> instance_;
+ TraceWrapperV8Reference<v8::Value> instance_;
Member<EffectProxy> effect_;
};
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
index c9789998870..0ce6e7feb26 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -57,13 +57,6 @@ bool ConvertAnimationEffects(
return false;
}
- if (keyframe_effects.size() > 1) {
- // TODO(yigu): We should allow group effects eventually by spec. See
- // crbug.com/767043.
- error_string = "Multiple effects are not currently supported";
- return false;
- }
-
// TODO(crbug.com/781816): Allow using effects with no target.
for (const auto& effect : keyframe_effects) {
if (!effect->target()) {
@@ -82,6 +75,21 @@ bool ConvertAnimationEffects(
return true;
}
+bool IsActive(const Animation::AnimationPlayState& state) {
+ switch (state) {
+ case Animation::kIdle:
+ case Animation::kPending:
+ return false;
+ case Animation::kRunning:
+ case Animation::kPaused:
+ return true;
+ default:
+ // kUnset and kFinished are not used in WorkletAnimation.
+ NOTREACHED();
+ return false;
+ }
+}
+
bool ValidateTimeline(const DocumentTimelineOrScrollTimeline& timeline,
String& error_string) {
if (timeline.IsScrollTimeline()) {
@@ -140,6 +148,10 @@ CompositorScrollTimeline::ScrollDirection ConvertOrientation(
case ScrollTimeline::Inline:
return is_horizontal_writing_mode ? CompositorScrollTimeline::Horizontal
: CompositorScrollTimeline::Vertical;
+ case ScrollTimeline::Horizontal:
+ return CompositorScrollTimeline::Horizontal;
+ case ScrollTimeline::Vertical:
+ return CompositorScrollTimeline::Vertical;
default:
NOTREACHED();
return CompositorScrollTimeline::Vertical;
@@ -227,13 +239,6 @@ WorkletAnimation* WorkletAnimation::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
- if (!Platform::Current()->IsThreadedAnimationEnabled()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "AnimationWorklet requires threaded animations to be enabled");
- return nullptr;
- }
-
HeapVector<Member<KeyframeEffect>> keyframe_effects;
String error_string;
if (!ConvertAnimationEffects(effects, keyframe_effects, error_string)) {
@@ -275,16 +280,18 @@ WorkletAnimation::WorkletAnimation(
id_(id),
animator_name_(animator_name),
play_state_(Animation::kIdle),
+ last_play_state_(play_state_),
document_(document),
effects_(effects),
timeline_(timeline),
options_(std::make_unique<WorkletAnimationOptions>(options)),
effect_needs_restart_(false) {
DCHECK(IsMainThread());
- DCHECK(Platform::Current()->IsThreadedAnimationEnabled());
- AnimationEffect* target_effect = effects_.at(0);
- target_effect->Attach(this);
+ for (auto& effect : effects_) {
+ AnimationEffect* target_effect = effect;
+ target_effect->Attach(this);
+ }
if (timeline_->IsScrollTimeline())
ToScrollTimeline(timeline_)->AttachAnimation();
@@ -295,20 +302,29 @@ String WorkletAnimation::playState() {
return Animation::PlayStateString(play_state_);
}
-void WorkletAnimation::play() {
+void WorkletAnimation::play(ExceptionState& exception_state) {
DCHECK(IsMainThread());
if (play_state_ == Animation::kPending)
return;
- document_->GetWorkletAnimationController().AttachAnimation(*this);
- play_state_ = Animation::kPending;
- Element* target = GetEffect()->target();
- if (!target)
+ String failure_message;
+ if (!CheckCanStart(&failure_message)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ failure_message);
return;
- target->EnsureElementAnimations().GetWorkletAnimations().insert(this);
- // TODO(majidvp): This should be removed once worklet animation correctly
- // updates its effect timing. https://crbug.com/814851.
- target->SetNeedsAnimationStyleRecalc();
+ }
+
+ document_->GetWorkletAnimationController().AttachAnimation(*this);
+ SetPlayState(Animation::kPending);
+
+ for (auto& effect : effects_) {
+ Element* target = effect->target();
+ DCHECK(target);
+ target->EnsureElementAnimations().GetWorkletAnimations().insert(this);
+ // TODO(majidvp): This should be removed once worklet animation correctly
+ // updates its effect timing. https://crbug.com/814851.
+ target->SetNeedsAnimationStyleRecalc();
+ }
}
void WorkletAnimation::cancel() {
@@ -322,15 +338,27 @@ void WorkletAnimation::cancel() {
DestroyCompositorAnimation();
}
- play_state_ = Animation::kIdle;
-
- Element* target = GetEffect()->target();
- if (!target)
- return;
- target->EnsureElementAnimations().GetWorkletAnimations().erase(this);
- // TODO(majidvp): This should be removed once worklet animation correctly
- // updates its effect timing. https://crbug.com/814851.
- target->SetNeedsAnimationStyleRecalc();
+ local_time_ = base::nullopt;
+ start_time_ = base::nullopt;
+ running_on_main_thread_ = false;
+ // TODO(yigu): Because this animation has been detached and will not receive
+ // updates anymore, we have to update its value upon cancel. Similar to
+ // regular animations, we should not detach them immediately and update the
+ // value in the next frame. See https://crbug.com/883312.
+ if (IsActive(play_state_)) {
+ for (auto& effect : effects_)
+ effect->UpdateInheritedTime(NullValue(), kTimingUpdateOnDemand);
+ }
+ SetPlayState(Animation::kIdle);
+
+ for (auto& effect : effects_) {
+ Element* target = effect->target();
+ DCHECK(target);
+ target->EnsureElementAnimations().GetWorkletAnimations().erase(this);
+ // TODO(majidvp): This should be removed once worklet animation correctly
+ // updates its effect timing. https://crbug.com/814851.
+ target->SetNeedsAnimationStyleRecalc();
+ }
}
bool WorkletAnimation::Playing() const {
@@ -344,8 +372,7 @@ void WorkletAnimation::UpdateIfNecessary() {
}
void WorkletAnimation::EffectInvalidated() {
- effect_needs_restart_ = true;
- document_->GetWorkletAnimationController().InvalidateAnimation(*this);
+ InvalidateCompositingState();
}
void WorkletAnimation::Update(TimingUpdateReason reason) {
@@ -355,40 +382,92 @@ void WorkletAnimation::Update(TimingUpdateReason reason) {
if (!start_time_)
return;
- // TODO(crbug.com/756359): For now we use 0 as inherited time in but we will
- // need to get the inherited time from worklet context.
+ // TODO(crbug.com/756539): For now we use 0 as inherited time for compositor
+ // worklet animations. Will need to get the inherited time from worklet
+ // context.
double inherited_time_seconds = 0;
- GetEffect()->UpdateInheritedTime(inherited_time_seconds, reason);
+
+ if (local_time_)
+ inherited_time_seconds = local_time_->InSecondsF();
+
+ for (auto& effect : effects_)
+ effect->UpdateInheritedTime(inherited_time_seconds, reason);
}
-bool WorkletAnimation::UpdateCompositingState() {
- switch (play_state_) {
- case Animation::kPending: {
- String failure_message;
- if (StartOnCompositor(&failure_message))
- return true;
- document_->AddConsoleMessage(ConsoleMessage::Create(
- kOtherMessageSource, kWarningMessageLevel, failure_message));
- return false;
+bool WorkletAnimation::CheckCanStart(String* failure_message) {
+ DCHECK(IsMainThread());
+
+ for (auto& effect : effects_) {
+ if (effect->Model()->HasFrames())
+ continue;
+ *failure_message = "Animation effect has no keyframes";
+ return false;
+ }
+
+ return true;
+}
+
+void WorkletAnimation::SetStartTimeToNow() {
+ DCHECK(!start_time_);
+ bool is_null;
+ double time = timeline_->currentTime(is_null);
+ if (!is_null)
+ start_time_ = base::TimeDelta::FromSecondsD(time);
+}
+
+void WorkletAnimation::UpdateCompositingState() {
+ DCHECK(play_state_ != Animation::kIdle && play_state_ != Animation::kUnset);
+
+ if (play_state_ == Animation::kPending) {
+ String warning_message;
+ DCHECK(CheckCanStart(&warning_message));
+ DCHECK(warning_message.IsEmpty());
+ if (StartOnCompositor(&warning_message)) {
+ return;
}
- case Animation::kRunning: {
+ String message = "The animation cannot be accelerated. Reason: ";
+ message = message + warning_message;
+ document_->AddConsoleMessage(ConsoleMessage::Create(
+ kOtherMessageSource, kWarningMessageLevel, message));
+ StartOnMain();
+ } else if (play_state_ == Animation::kRunning) {
+ // TODO(majidvp): If keyframes have changed then it may be possible to now
+ // run the animation on compositor. The current logic does not allow this
+ // switch from main to compositor to happen.
+ if (!running_on_main_thread_)
UpdateOnCompositor();
- return false;
- }
- default:
- return false;
}
+ DCHECK(running_on_main_thread_ != !!compositor_animation_)
+ << "Active worklet animation should either run on main or compositor";
+}
+
+void WorkletAnimation::InvalidateCompositingState() {
+ effect_needs_restart_ = true;
+ document_->GetWorkletAnimationController().InvalidateAnimation(*this);
+}
+
+void WorkletAnimation::StartOnMain() {
+ running_on_main_thread_ = true;
+ SetStartTimeToNow();
+ SetPlayState(Animation::kRunning);
}
bool WorkletAnimation::StartOnCompositor(String* failure_message) {
DCHECK(IsMainThread());
+ if (effects_.size() > 1) {
+ // Compositor doesn't support multiple effects but they can be run via main.
+ *failure_message =
+ "Multiple effects with composited properties are not currently "
+ "supported on compositor";
+ return false;
+ }
+
Element& target = *GetEffect()->target();
// TODO(crbug.com/836393): This should not be possible but it is currently
// happening and needs to be investigated/fixed.
if (!target.GetComputedStyle()) {
- if (failure_message)
- *failure_message = "The target element does not have style.";
+ *failure_message = "The target element does not have style";
return false;
}
// CheckCanStartAnimationOnCompositor requires that the property-specific
@@ -398,21 +477,19 @@ bool WorkletAnimation::StartOnCompositor(String* failure_message) {
GetEffect()->Model()->SnapshotAllCompositorKeyframesIfNecessary(
target, target.ComputedStyleRef(), target.ParentComputedStyle());
- if (!CheckElementComposited(target)) {
- if (failure_message)
- *failure_message = "The target element is not composited.";
- return false;
- }
-
double playback_rate = 1;
CompositorAnimations::FailureCode failure_code =
GetEffect()->CheckCanStartAnimationOnCompositor(
base::Optional<CompositorElementIdSet>(), playback_rate);
if (!failure_code.Ok()) {
- play_state_ = Animation::kIdle;
- if (failure_message)
- *failure_message = failure_code.reason;
+ SetPlayState(Animation::kIdle);
+ *failure_message = failure_code.reason;
+ return false;
+ }
+
+ if (!CheckElementComposited(target)) {
+ *failure_message = "The target element is not composited";
return false;
}
@@ -434,12 +511,12 @@ bool WorkletAnimation::StartOnCompositor(String* failure_message) {
// TODO(smcgruer): We need to start all of the effects, not just the first.
StartEffectOnCompositor(compositor_animation_.get(), GetEffect());
- play_state_ = Animation::kRunning;
+ SetPlayState(Animation::kRunning);
bool is_null;
double time = timeline_->currentTime(is_null);
if (!is_null)
- start_time_ = time;
+ start_time_ = base::TimeDelta::FromSecondsD(time);
return true;
}
@@ -480,6 +557,50 @@ KeyframeEffect* WorkletAnimation::GetEffect() const {
return effects_.at(0);
}
+bool WorkletAnimation::IsActiveAnimation() const {
+ return IsActive(play_state_);
+}
+
+void WorkletAnimation::UpdateInputState(
+ AnimationWorkletDispatcherInput* input_state) {
+ if (!running_on_main_thread_) {
+ input_state->Peek(id_);
+ return;
+ }
+
+ bool was_active = IsActive(last_play_state_);
+ bool is_active = IsActive(play_state_);
+
+ DCHECK(start_time_);
+ DCHECK(last_current_time_ || !was_active);
+ bool is_null;
+ double current_time = timeline_->currentTime(is_null);
+
+ bool did_time_change =
+ !last_current_time_ || current_time != last_current_time_->InSecondsF();
+ last_current_time_ = base::TimeDelta::FromSecondsD(current_time);
+
+ if (!was_active && is_active) {
+ input_state->Add(
+ {id_,
+ std::string(animator_name_.Ascii().data(), animator_name_.length()),
+ current_time, CloneOptions()});
+ } else if (was_active && is_active) {
+ // Skip if the input time is not changed.
+ if (did_time_change)
+ input_state->Update({id_, current_time});
+ } else if (was_active && !is_active) {
+ input_state->Remove(id_);
+ }
+ last_play_state_ = play_state_;
+}
+
+void WorkletAnimation::SetOutputState(
+ const AnimationWorkletOutput::AnimationState& state) {
+ DCHECK(state.worklet_animation_id == id_);
+ local_time_ = state.local_time;
+}
+
void WorkletAnimation::Dispose() {
DCHECK(IsMainThread());
if (timeline_->IsScrollTimeline())
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
index c9977fd5a38..c8c6d5a22da 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
@@ -16,7 +16,7 @@
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_animators_state.h"
+#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutators_state.h"
namespace blink {
@@ -66,7 +66,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
AnimationTimeline* timeline() { return timeline_; }
String playState();
- void play();
+ void play(ExceptionState& exception_state);
void cancel();
// AnimationEffectOwner implementation:
@@ -87,7 +87,8 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
// WorkletAnimationBase implementation.
void Update(TimingUpdateReason) override;
- bool UpdateCompositingState() override;
+ void UpdateCompositingState() override;
+ void InvalidateCompositingState() override;
// CompositorAnimationClient implementation.
CompositorAnimation* GetCompositorAnimation() const override {
@@ -106,6 +107,14 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
const String& Name() { return animator_name_; }
KeyframeEffect* GetEffect() const override;
+ const WorkletAnimationId& GetWorkletAnimationId() const override {
+ return id_;
+ }
+ bool IsActiveAnimation() const override;
+
+ void UpdateInputState(AnimationWorkletDispatcherInput* input_state) override;
+ void SetOutputState(
+ const AnimationWorkletOutput::AnimationState& state) override;
void Trace(blink::Visitor*) override;
@@ -119,21 +128,38 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
void DestroyCompositorAnimation();
// Attempts to start the animation on the compositor side, returning true if
- // it succeeds or false otherwise. If false is returned and failure_message
- // was non-null, failure_message may be filled with an error description.
+ // it succeeds or false otherwise. If false is returned and the animation
+ // cannot be started on main and failure_message was non-null, failure_message
+ // may be filled with an error description.
bool StartOnCompositor(String* failure_message);
+ void StartOnMain();
+ bool CheckCanStart(String* failure_message);
+ void SetStartTimeToNow();
// Updates a running animation on the compositor side.
void UpdateOnCompositor();
+ std::unique_ptr<cc::AnimationOptions> CloneOptions() const {
+ return options_ ? options_->Clone() : nullptr;
+ }
+
+ void SetPlayState(const Animation::AnimationPlayState& state) {
+ play_state_ = state;
+ }
+
unsigned sequence_number_;
WorkletAnimationId id_;
const String animator_name_;
Animation::AnimationPlayState play_state_;
+ Animation::AnimationPlayState last_play_state_;
// Start time in ms.
- base::Optional<double> start_time_;
+ base::Optional<base::TimeDelta> start_time_;
+ base::Optional<base::TimeDelta> local_time_;
+ // We use this to skip updating if current time has not changed since last
+ // update.
+ base::Optional<base::TimeDelta> last_current_time_;
Member<Document> document_;
@@ -142,6 +168,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
std::unique_ptr<WorkletAnimationOptions> options_;
std::unique_ptr<CompositorAnimation> compositor_animation_;
+ bool running_on_main_thread_;
// Tracks whether any KeyframeEffect associated with this WorkletAnimation has
// been invalidated and needs to be restarted. Used to avoid unnecessarily
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
index 675fec20c1f..0f7a4feb633 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
@@ -18,6 +18,6 @@
] interface WorkletAnimation {
readonly attribute AnimationTimeline? timeline;
readonly attribute AnimationPlayState playState;
- void play();
+ [RaisesException] void play();
void cancel();
};
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
index ca3880c3278..225c0807761 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
@@ -35,7 +35,7 @@ KeyframeEffectModelBase* CreateEffectModel() {
KeyframeEffect* CreateKeyframeEffect(Element* element) {
Timing timing;
- timing.iteration_duration = 30;
+ timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
return KeyframeEffect::Create(element, CreateEffectModel(), timing);
}
@@ -76,7 +76,8 @@ class WorkletAnimationTest : public RenderingTest {
};
TEST_F(WorkletAnimationTest, WorkletAnimationInElementAnimations) {
- worklet_animation_->play();
+ DummyExceptionStateForTesting exception_state;
+ worklet_animation_->play(exception_state);
EXPECT_EQ(1u,
element_->EnsureElementAnimations().GetWorkletAnimations().size());
worklet_animation_->cancel();
@@ -88,7 +89,8 @@ TEST_F(WorkletAnimationTest, StyleHasCurrentAnimation) {
scoped_refptr<ComputedStyle> style =
GetDocument().EnsureStyleResolver().StyleForElement(element_).get();
EXPECT_EQ(false, style->HasCurrentOpacityAnimation());
- worklet_animation_->play();
+ DummyExceptionStateForTesting exception_state;
+ worklet_animation_->play(exception_state);
element_->EnsureElementAnimations().UpdateAnimationFlags(*style);
EXPECT_EQ(true, style->HasCurrentOpacityAnimation());
}
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
index 333d7bc3947..bd1c1a095ed 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
+++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc
@@ -80,10 +80,10 @@ ScriptPromise BeforeInstallPromptEvent::prompt(ScriptState* script_state) {
}
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = To<Document>(context);
- if (require_gesture_ &&
- !Frame::ConsumeTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ if (require_gesture_ && !LocalFrame::ConsumeTransientUserActivation(
+ doc ? doc->GetFrame() : nullptr)) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.cc b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.cc
index fa18d821a0f..fde89244bde 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.cc
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.cc
@@ -16,17 +16,12 @@ AudioOutputDeviceClient::AudioOutputDeviceClient(LocalFrame& frame)
const char AudioOutputDeviceClient::kSupplementName[] =
"AudioOutputDeviceClient";
-AudioOutputDeviceClient* AudioOutputDeviceClient::From(
- ExecutionContext* context) {
- if (!context || !context->IsDocument())
- return nullptr;
-
- const Document* document = ToDocument(context);
- if (!document->GetFrame())
+AudioOutputDeviceClient* AudioOutputDeviceClient::From(Document& document) {
+ if (!document.GetFrame())
return nullptr;
return Supplement<LocalFrame>::From<AudioOutputDeviceClient>(
- document->GetFrame());
+ document.GetFrame());
}
void ProvideAudioOutputDeviceClientTo(LocalFrame& frame,
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h
index 3ed14c55ee8..ac712d54519 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h
@@ -13,7 +13,7 @@
namespace blink {
-class ExecutionContext;
+class Document;
class WebString;
class MODULES_EXPORT AudioOutputDeviceClient : public Supplement<LocalFrame> {
@@ -26,14 +26,14 @@ class MODULES_EXPORT AudioOutputDeviceClient : public Supplement<LocalFrame> {
// Checks that a given sink exists and has permissions to be used from the
// origin of the current frame.
virtual void CheckIfAudioSinkExistsAndIsAuthorized(
- ExecutionContext*,
+ Document&,
const WebString& sink_id,
std::unique_ptr<WebSetSinkIdCallbacks>) = 0;
void Trace(blink::Visitor*) override;
// Supplement requirements.
- static AudioOutputDeviceClient* From(ExecutionContext*);
+ static AudioOutputDeviceClient* From(Document&);
};
MODULES_EXPORT void ProvideAudioOutputDeviceClientTo(LocalFrame&,
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.cc b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.cc
index 7eb90d424ed..26012a3ae68 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.cc
@@ -18,14 +18,11 @@ AudioOutputDeviceClientImpl::AudioOutputDeviceClientImpl(LocalFrame& frame)
AudioOutputDeviceClientImpl::~AudioOutputDeviceClientImpl() = default;
void AudioOutputDeviceClientImpl::CheckIfAudioSinkExistsAndIsAuthorized(
- ExecutionContext* context,
+ Document& document,
const WebString& sink_id,
std::unique_ptr<WebSetSinkIdCallbacks> callbacks) {
- DCHECK(context);
- DCHECK(context->IsDocument());
- Document* document = ToDocument(context);
WebLocalFrameImpl* web_frame =
- WebLocalFrameImpl::FromFrame(document->GetFrame());
+ WebLocalFrameImpl::FromFrame(document.GetFrame());
web_frame->Client()->CheckIfAudioSinkExistsAndIsAuthorized(
sink_id, callbacks.release());
}
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.h b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.h
index a99b5f60738..6d42f29402d 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.h
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client_impl.h
@@ -25,7 +25,7 @@ class MODULES_EXPORT AudioOutputDeviceClientImpl
// AudioOutputDeviceClient implementation.
void CheckIfAudioSinkExistsAndIsAuthorized(
- ExecutionContext*,
+ Document&,
const WebString& sink_id,
std::unique_ptr<WebSetSinkIdCallbacks>) override;
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
index d14d53257ee..76e72a8ea2c 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/audio_output_devices/audio_output_device_client.h"
@@ -67,8 +68,6 @@ void SetSinkIdResolver::StartAsync() {
void SetSinkIdResolver::TimerFired(TimerBase* timer) {
ExecutionContext* context = GetExecutionContext();
- DCHECK(context);
- DCHECK(context->IsDocument());
std::unique_ptr<SetSinkIdCallbacks> callbacks =
std::make_unique<SetSinkIdCallbacks>(this, *element_, sink_id_);
WebMediaPlayer* web_media_player = element_->GetWebMediaPlayer();
@@ -78,9 +77,10 @@ void SetSinkIdResolver::TimerFired(TimerBase* timer) {
web_media_player->SetSinkId(sink_id_,
callbacks.release());
} else {
+ auto& document = *To<Document>(context);
if (AudioOutputDeviceClient* client =
- AudioOutputDeviceClient::From(context)) {
- client->CheckIfAudioSinkExistsAndIsAuthorized(context, sink_id_,
+ AudioOutputDeviceClient::From(document)) {
+ client->CheckIfAudioSinkExistsAndIsAuthorized(document, sink_id_,
std::move(callbacks));
} else {
// The context has been detached. Impossible to get a security origin to
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h b/chromium/third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h
index 3bf22ca4c8e..acb45844512 100644
--- a/chromium/third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h
@@ -7,7 +7,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/web_set_sink_id_callbacks.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
index e5bc03686bc..022104ceead 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
@@ -64,10 +64,11 @@ void BackgroundFetchBridge::Fetch(
Vector<WebServiceWorkerRequest> requests,
mojom::blink::BackgroundFetchOptionsPtr options,
const SkBitmap& icon,
+ mojom::blink::BackgroundFetchUkmDataPtr ukm_data,
RegistrationCallback callback) {
GetService()->Fetch(
GetSupplementable()->WebRegistration()->RegistrationId(), developer_id,
- std::move(requests), std::move(options), icon,
+ std::move(requests), std::move(options), icon, std::move(ukm_data),
WTF::Bind(&BackgroundFetchBridge::DidGetRegistration,
WrapPersistent(this), WTF::Passed(std::move(callback))));
}
@@ -112,7 +113,7 @@ void BackgroundFetchBridge::DidGetRegistration(
if (registration) {
DCHECK_EQ(error, mojom::blink::BackgroundFetchError::NONE);
- DCHECK_EQ(registration->state(), "pending");
+ DCHECK_EQ(registration->result(), "");
registration->Initialize(GetSupplementable());
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
index b6dba87ebab..f295ce6d1c7 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
@@ -54,6 +54,7 @@ class BackgroundFetchBridge final
Vector<WebServiceWorkerRequest> requests,
mojom::blink::BackgroundFetchOptionsPtr options,
const SkBitmap& icon,
+ mojom::blink::BackgroundFetchUkmDataPtr ukm_data,
RegistrationCallback callback);
// Gets the size of the icon to be displayed in Background Fetch UI.
@@ -62,7 +63,7 @@ class BackgroundFetchBridge final
// Matches completed requests for the fetch associated with the |developer_id|
// and |unique_id| and returns the {request, response} pairs based on the rest
// of the arguments. If |filter_by_request| is true, only response(s) for
- // |request_to_match| are returned. |cache_query_params| are options for the
+ // |request_to_match| are returned. |cache_query_params|s are options for the
// query to the cache storage. |match_all|, when true, returns all responses
// from the result set, and when false, returns only the first one.
void MatchRequests(
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
index e4c633e4e3c..65c470ad54e 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
@@ -7,7 +7,7 @@
[
Constructor(DOMString type, BackgroundFetchEventInit init),
Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchEvent : ExtendableEvent {
readonly attribute BackgroundFetchRegistration registration;
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fetch.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fetch.idl
index c87e1568886..df03e494252 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fetch.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fetch.idl
@@ -6,7 +6,7 @@
[
Exposed=(Window,Worker),
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchFetch {
readonly attribute Request request;
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
index 419441d0ecb..813131fc695 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -71,14 +71,16 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
// If |icon_display_size_pixels_| is empty then no image will be displayed by
// the UI powering Background Fetch. Bail out immediately.
if (icon_display_size_pixels_.IsEmpty()) {
- std::move(icon_callback).Run(SkBitmap());
+ std::move(icon_callback)
+ .Run(SkBitmap(), -1 /* ideal_to_chosen_icon_size_times_hundred */);
return;
}
KURL best_icon_url = PickBestIconForDisplay(execution_context);
if (best_icon_url.IsEmpty()) {
// None of the icons provided was suitable.
- std::move(icon_callback).Run(SkBitmap());
+ std::move(icon_callback)
+ .Run(SkBitmap(), -1 /* ideal_to_chosen_icon_size_times_hundred */);
return;
}
@@ -89,9 +91,14 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
resource_loader_options.request_initiator_context = kWorkerContext;
ResourceRequest resource_request(best_icon_url);
- resource_request.SetRequestContext(WebURLRequest::kRequestContextImage);
+ resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
resource_request.SetPriority(ResourceLoadPriority::kMedium);
- resource_request.SetRequestorOrigin(execution_context->GetSecurityOrigin());
+ resource_request.SetKeepalive(true);
+ resource_request.SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kNoCORS);
+ resource_request.SetFetchCredentialsMode(
+ network::mojom::FetchCredentialsMode::kInclude);
+ resource_request.SetSkipServiceWorker(true);
threadable_loader_ =
new ThreadableLoader(*execution_context, this, resource_loader_options);
@@ -107,10 +114,18 @@ KURL BackgroundFetchIconLoader::PickBestIconForDisplay(
// Update the src of |icon| to include the base URL in case relative paths
// were used.
icon.setSrc(execution_context->CompleteURL(icon.src()));
- icons.emplace_back(blink::ConvertManifestImageResource(icon));
+ Manifest::ImageResource candidate_icon =
+ blink::ConvertManifestImageResource(icon);
+ // Provide default values for 'purpose' and 'sizes' if they are missing.
+ if (candidate_icon.sizes.empty())
+ candidate_icon.sizes.emplace_back(gfx::Size(0, 0));
+ if (candidate_icon.purpose.empty()) {
+ candidate_icon.purpose.emplace_back(
+ Manifest::ImageResource::Purpose::ANY);
+ }
+ icons.emplace_back(candidate_icon);
}
- // TODO(crbug.com/868875): Handle cases where `sizes` or `purpose` is empty.
return KURL(ManifestIconSelector::FindBestMatchingIcon(
std::move(icons), icon_display_size_pixels_.height, kMinimumIconSizeInPx,
Manifest::ImageResource::Purpose::ANY));
@@ -161,14 +176,12 @@ void BackgroundFetchIconLoader::DecodeAndResizeImageOnBackgroundThread(
DCHECK(task_runner);
DCHECK(data);
- // Explicitly pass in the |icon_display_size_pixels_| to benefit from decoders
- // that have optimizations for partial decoding.
std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
std::move(data), /* data_complete= */ true,
ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
- ColorBehavior::TransformToSRGB(),
- {icon_display_size_pixels_.width, icon_display_size_pixels_.height});
+ ColorBehavior::TransformToSRGB());
+ int64_t ideal_to_chosen_icon_size_times_hundred = -1;
if (decoder) {
ImageFrame* image_frame = decoder->DecodeFrameBufferAtIndex(0);
if (image_frame) {
@@ -184,6 +197,8 @@ void BackgroundFetchIconLoader::DecodeAndResizeImageOnBackgroundThread(
static_cast<double>(icon_display_size_pixels_.width) / width,
static_cast<double>(icon_display_size_pixels_.height) / height);
+ ideal_to_chosen_icon_size_times_hundred = std::round(scale * 100.0);
+
if (scale < 1) {
width = ClampToRange(scale * width, 1, icon_display_size_pixels_.width);
height =
@@ -200,7 +215,8 @@ void BackgroundFetchIconLoader::DecodeAndResizeImageOnBackgroundThread(
PostCrossThreadTask(*task_runner, FROM_HERE,
CrossThreadBind(&BackgroundFetchIconLoader::RunCallback,
- WrapCrossThreadPersistent(this)));
+ WrapCrossThreadPersistent(this),
+ ideal_to_chosen_icon_size_times_hundred));
}
void BackgroundFetchIconLoader::DidFail(const ResourceError& error) {
@@ -211,18 +227,20 @@ void BackgroundFetchIconLoader::DidFailRedirectCheck() {
RunCallbackWithEmptyBitmap();
}
-void BackgroundFetchIconLoader::RunCallback() {
+void BackgroundFetchIconLoader::RunCallback(
+ int64_t ideal_to_chosen_icon_size_times_hundred) {
// If this has been stopped it is not desirable to trigger further work,
// there is a shutdown of some sort in progress.
if (stopped_)
return;
- std::move(icon_callback_).Run(decoded_icon_);
+ std::move(icon_callback_)
+ .Run(decoded_icon_, ideal_to_chosen_icon_size_times_hundred);
}
void BackgroundFetchIconLoader::RunCallbackWithEmptyBitmap() {
DCHECK(decoded_icon_.isNull());
- RunCallback();
+ RunCallback(-1 /* ideal_to_chosen_icon_size_times_hundred */);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
index 2e7a2c83d66..180699c417d 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h
@@ -24,9 +24,11 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
: public GarbageCollectedFinalized<BackgroundFetchIconLoader>,
public ThreadableLoaderClient {
public:
- // The bitmap may be empty if the request failed or the image data
- // could not be decoded.
- using IconCallback = base::OnceCallback<void(const SkBitmap&)>;
+ // The bitmap may be empty if the request failed or the image data could not
+ // be decoded. The int64_t returned is the scale of the ideal to chosen icon,
+ // before resizing. This is -1 if the ideal icon size is empty, or if no icon
+ // provided was suitable.
+ using IconCallback = base::OnceCallback<void(const SkBitmap&, int64_t)>;
BackgroundFetchIconLoader();
~BackgroundFetchIconLoader() override;
@@ -56,7 +58,7 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
private:
friend class BackgroundFetchIconLoaderTest;
- void RunCallback();
+ void RunCallback(int64_t ideal_to_chosen_icon_size_times_hundred);
void RunCallbackWithEmptyBitmap();
// Callback for BackgroundFetchBridge::GetIconDisplaySize()
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
index f0b678602c2..76709846e49 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc
@@ -64,7 +64,9 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
// Callback for BackgroundFetchIconLoader. This will set up the state of the
// load as either success or failed based on whether the bitmap is empty.
- void IconLoaded(base::OnceClosure quit_closure, const SkBitmap& bitmap) {
+ void IconLoaded(base::OnceClosure quit_closure,
+ const SkBitmap& bitmap,
+ int64_t ideal_to_chosen_icon_size) {
bitmap_ = bitmap;
if (!bitmap_.isNull())
@@ -95,12 +97,14 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
void LoadIcon(const KURL& url,
const WebSize& maximum_size,
- base::OnceClosure quit_closure) {
+ base::OnceClosure quit_closure,
+ const String& sizes = "500x500",
+ const String& purpose = "ANY") {
ManifestImageResource icon;
icon.setSrc(url.GetString());
icon.setType("image/png");
- icon.setSizes("500x500");
- icon.setPurpose("ANY");
+ icon.setSizes(sizes);
+ icon.setPurpose(purpose);
HeapVector<ManifestImageResource> icons(1, icon);
loader_->icons_ = std::move(icons);
loader_->DidGetIconDisplaySizeIfSoLoadIcon(
@@ -181,4 +185,34 @@ TEST_F(BackgroundFetchIconLoaderTest, PickRightIcon) {
kBackgroundFetchImageLoaderIcon48x48));
}
+TEST_F(BackgroundFetchIconLoaderTest, EmptySizes) {
+ base::RunLoop run_loop;
+
+ WebSize maximum_size{192, 168};
+ LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
+ run_loop.QuitClosure(), "", "ANY");
+
+ platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+
+ run_loop.Run();
+
+ ASSERT_EQ(BackgroundFetchLoadState::kLoadSuccessful, loaded_);
+ ASSERT_FALSE(bitmap_.drawsNothing());
+}
+
+TEST_F(BackgroundFetchIconLoaderTest, EmptyPurpose) {
+ base::RunLoop run_loop;
+
+ WebSize maximum_size{192, 168};
+ LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
+ run_loop.QuitClosure(), "500X500", "");
+
+ platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+
+ run_loop.Run();
+
+ ASSERT_EQ(BackgroundFetchLoadState::kLoadSuccessful, loaded_);
+ ASSERT_FALSE(bitmap_.drawsNothing());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
index dbe549d7100..58d84e020b7 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -4,20 +4,16 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h"
-#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/fetch/body.h"
-#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
-#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_options.h"
@@ -27,13 +23,14 @@
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
-#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
@@ -86,14 +83,6 @@ bool ShouldBlockScheme(const KURL& request_url) {
!request_url.ProtocolIs(WTF::g_https_atom);
}
-bool ShouldBlockMixedContent(ExecutionContext* execution_context,
- const KURL& request_url) {
- // TODO(crbug.com/757441): Using MixedContentChecker::ShouldBlockFetch would
- // log better metrics.
- return MixedContentChecker::IsMixedContent(
- execution_context->GetSecurityOrigin(), request_url);
-}
-
bool ShouldBlockDanglingMarkup(const KURL& request_url) {
// "If request's url's potentially-dangling-markup flag is set, and request's
// url's scheme is an HTTP(S) scheme, then set response to a network error."
@@ -103,29 +92,9 @@ bool ShouldBlockDanglingMarkup(const KURL& request_url) {
request_url.ProtocolIsInHTTPFamily();
}
-bool ShouldBlockCORSPreflight(ExecutionContext* execution_context,
- const WebServiceWorkerRequest& web_request,
- const KURL& request_url) {
- // Requests that require CORS preflights are temporarily blocked, because the
- // browser side of Background Fetch doesn't yet support performing CORS
- // checks. TODO(crbug.com/711354): Remove this temporary block.
-
- // Same origin requests don't require a CORS preflight.
- // https://fetch.spec.whatwg.org/#main-fetch
- // TODO(crbug.com/711354): Make sure that cross-origin redirects are disabled.
- bool same_origin =
- execution_context->GetSecurityOrigin()->CanRequest(request_url);
- if (same_origin)
- return false;
-
- // Requests that are more involved than what is possible with HTML's form
- // element require a CORS-preflight request.
- // https://fetch.spec.whatwg.org/#main-fetch
- if (!CORS::IsCORSSafelistedMethod(web_request.Method()) ||
- !CORS::ContainsOnlyCORSSafelistedHeaders(web_request.Headers())) {
- return true;
- }
-
+bool ShouldBlockGateWayAttacks(ExecutionContext* execution_context,
+ const WebServiceWorkerRequest& web_request,
+ const KURL& request_url) {
if (RuntimeEnabledFeatures::CorsRFC1918Enabled()) {
mojom::IPAddressSpace requestor_space =
execution_context->GetSecurityContext().AddressSpace();
@@ -147,38 +116,12 @@ bool ShouldBlockCORSPreflight(ExecutionContext* execution_context,
return false;
}
-scoped_refptr<BlobDataHandle> ExtractBlobHandle(
- Request* request,
- ExceptionState& exception_state) {
- DCHECK(request);
-
- if (request->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked ||
- request->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
- DCHECK(!exception_state.HadException());
- exception_state.ThrowTypeError("Request body is already used");
- return nullptr;
- }
-
- BodyStreamBuffer* buffer = request->BodyBuffer();
- if (!buffer)
- return nullptr;
-
- auto blob_handle = buffer->DrainAsBlobDataHandle(
- BytesConsumer::BlobSizePolicy::kDisallowBlobWithInvalidSize,
- exception_state);
- if (exception_state.HadException())
- return nullptr;
-
- return blob_handle;
-}
-
} // namespace
BackgroundFetchManager::BackgroundFetchManager(
ServiceWorkerRegistration* registration)
: ContextLifecycleObserver(registration->GetExecutionContext()),
- registration_(registration),
- loader_(new BackgroundFetchIconLoader()) {
+ registration_(registration) {
DCHECK(registration);
bridge_ = BackgroundFetchBridge::From(registration_);
}
@@ -197,27 +140,37 @@ ScriptPromise BackgroundFetchManager::fetch(
"the ServiceWorkerRegistration."));
}
- Vector<WebServiceWorkerRequest> web_requests =
- CreateWebRequestVector(script_state, requests, exception_state);
+ bool has_requests_with_body;
+ Vector<WebServiceWorkerRequest> web_requests = CreateWebRequestVector(
+ script_state, requests, exception_state, &has_requests_with_body);
if (exception_state.HadException())
return ScriptPromise();
+ // Record whether any requests had a body. If there were, reject the promise.
+ UMA_HISTOGRAM_BOOLEAN("BackgroundFetch.HasRequestsWithBody",
+ has_requests_with_body);
+
+ // TODO(crbug.com/789854): Stop bailing here once we support uploads.
+ if (has_requests_with_body) {
+ return ScriptPromise::Reject(
+ script_state, V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
+ "Requests with a body are not yet supported. "
+ "For updates check http://crbug.com/774054"));
+ }
+
ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ // A HashSet to find whether there are any duplicate requests within the
+ // fetch. https://bugs.chromium.org/p/chromium/issues/detail?id=871174.
+ HashSet<KURL> kurls;
+
// Based on security steps from https://fetch.spec.whatwg.org/#main-fetch
// TODO(crbug.com/757441): Remove all this duplicative code once Fetch (and
// all its security checks) are implemented in the Network Service, such that
// the Download Service in the browser process can use it without having to
// spin up a renderer process.
for (const WebServiceWorkerRequest& web_request : web_requests) {
- // TODO(crbug.com/757441): Decide whether to support upgrading requests to
- // potentially secure URLs (https://w3c.github.io/webappsec-upgrade-
- // insecure-requests/) and/or HSTS rewriting. Since this is a new API only
- // exposed on Secure Contexts, and the Mixed Content check below will block
- // any requests to insecure contexts, it'd be cleanest not to support it.
- // Depends how closely compatible with Fetch we want to be. If support is
- // added, make sure to report CSP violations before upgrading the URL.
-
KURL request_url(web_request.Url());
if (!request_url.IsValid()) {
@@ -234,7 +187,7 @@ ScriptPromise BackgroundFetchManager::fetch(
}
// Check this before mixed content, so that if mixed content is blocked by
- // CSP they get a CSP warning rather than a mixed content warning.
+ // CSP they get a CSP warning rather than a mixed content failure.
if (ShouldBlockDueToCSP(execution_context, request_url)) {
return RejectWithTypeError(script_state, request_url,
"it violates the Content Security Policy");
@@ -256,43 +209,61 @@ ScriptPromise BackgroundFetchManager::fetch(
"for loopback IPs");
}
- // Blocking fetches due to mixed content is done after Content Security
- // Policy to prioritize warnings caused by the latter.
- if (ShouldBlockMixedContent(execution_context, request_url)) {
- return RejectWithTypeError(script_state, request_url,
- "it is insecure; use https instead");
- }
-
if (ShouldBlockDanglingMarkup(request_url)) {
return RejectWithTypeError(script_state, request_url,
"it contains dangling markup");
}
- if (ShouldBlockCORSPreflight(execution_context, web_request, request_url)) {
+ if (ShouldBlockGateWayAttacks(execution_context, web_request,
+ request_url)) {
return RejectWithTypeError(script_state, request_url,
- "CORS preflights are not yet supported "
- "by this browser");
+ "Requestor IP address space doesn't match the "
+ "target address space.");
}
+
+ kurls.insert(request_url);
+ }
+
+ const bool has_duplicate_requests = kurls.size() != web_requests.size();
+
+ UMA_HISTOGRAM_BOOLEAN("BackgroundFetch.HasDuplicateRequests",
+ has_duplicate_requests);
+
+ // Note: This is a proprietary check, due to the way Chrome currently handles
+ // storing background fetch records. Entries are keyed by the URL, so if two
+ // requests have the same URL, and different responses, the first response
+ // will be lost when the second request/response pair is stored.
+ if (has_duplicate_requests) {
+ return ScriptPromise::Reject(
+ script_state,
+ V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
+ "Fetches with duplicate requests are not yet supported. "
+ "Consider adding query params to make the requests unique. "
+ "For updates check http://crbug.com/871174"));
}
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
- // Load Icons. Right now, we just load the first icon. Lack of icons or
- // inability to load them should not be fatal to the fetch.
+ // Pick the best icon, and load it.
+ // Inability to load them should not be fatal to the fetch.
mojom::blink::BackgroundFetchOptionsPtr options_ptr =
mojom::blink::BackgroundFetchOptions::From(options);
if (options.icons().size()) {
- loader_->Start(
+ BackgroundFetchIconLoader* loader = new BackgroundFetchIconLoader();
+ loaders_.push_back(loader);
+ loader->Start(
bridge_.Get(), execution_context, options.icons(),
WTF::Bind(&BackgroundFetchManager::DidLoadIcons, WrapPersistent(this),
id, WTF::Passed(std::move(web_requests)),
- std::move(options_ptr), WrapPersistent(resolver)));
+ std::move(options_ptr), WrapPersistent(resolver),
+ WrapWeakPersistent(loader)));
return promise;
}
DidLoadIcons(id, std::move(web_requests), std::move(options_ptr), resolver,
- SkBitmap());
+ nullptr, SkBitmap(), -1 /* ideal_to_chosen_icon_size */);
return promise;
}
@@ -301,9 +272,17 @@ void BackgroundFetchManager::DidLoadIcons(
Vector<WebServiceWorkerRequest> web_requests,
mojom::blink::BackgroundFetchOptionsPtr options,
ScriptPromiseResolver* resolver,
- const SkBitmap& icon) {
+ BackgroundFetchIconLoader* loader,
+ const SkBitmap& icon,
+ int64_t ideal_to_chosen_icon_size) {
+ if (loader)
+ loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader));
+
+ auto ukm_data = mojom::blink::BackgroundFetchUkmData::New();
+ ukm_data->ideal_to_chosen_icon_size = ideal_to_chosen_icon_size;
bridge_->Fetch(
id, std::move(web_requests), std::move(options), icon,
+ std::move(ukm_data),
WTF::Bind(&BackgroundFetchManager::DidFetch, WrapPersistent(this),
WrapPersistent(resolver), base::Time::Now()));
}
@@ -350,6 +329,11 @@ void BackgroundFetchManager::DidFetch(
resolver->Reject(DOMException::Create(
DOMExceptionCode::kQuotaExceededError, "Quota exceeded."));
return;
+ case mojom::blink::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED:
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
+ "There are too many active fetches for this origin."));
+ return;
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::INVALID_ID:
// Not applicable for this callback.
@@ -366,6 +350,15 @@ ScriptPromise BackgroundFetchManager::get(ScriptState* script_state,
if (!registration_->active())
return ScriptPromise::CastUndefined(script_state);
+ ScriptState::Scope scope(script_state);
+
+ if (id.IsEmpty()) {
+ return ScriptPromise::Reject(
+ script_state,
+ V8ThrowException::CreateTypeError(script_state->GetIsolate(),
+ "The provided id is invalid."));
+ }
+
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
@@ -381,8 +374,12 @@ ScriptPromise BackgroundFetchManager::get(ScriptState* script_state,
Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
ScriptState* script_state,
const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
- ExceptionState& exception_state) {
+ ExceptionState& exception_state,
+ bool* has_requests_with_body) {
+ DCHECK(has_requests_with_body);
+
Vector<WebServiceWorkerRequest> web_requests;
+ *has_requests_with_body = false;
if (requests.IsRequestOrUSVStringSequence()) {
HeapVector<RequestOrUSVString> request_vector =
@@ -396,7 +393,7 @@ Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
web_requests.resize(request_vector.size());
- for (size_t i = 0; i < request_vector.size(); ++i) {
+ for (wtf_size_t i = 0; i < request_vector.size(); ++i) {
const RequestOrUSVString& request_or_url = request_vector[i];
Request* request = nullptr;
@@ -413,16 +410,21 @@ Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
}
DCHECK(request);
+ *has_requests_with_body |= request->HasBody();
+ // TODO(crbug.com/774054): Set blob data handle when adding support for
+ // requests with body.
request->PopulateWebServiceWorkerRequest(web_requests[i]);
- web_requests[i].SetBlobDataHandle(
- ExtractBlobHandle(request, exception_state));
}
} else if (requests.IsRequest()) {
- DCHECK(requests.GetAsRequest());
+ auto* request = requests.GetAsRequest();
+ DCHECK(request);
+
+ // TODO(crbug.com/774054): Set blob data handle when adding support for
+ // requests with body.
+
+ *has_requests_with_body = request->HasBody();
web_requests.resize(1);
- requests.GetAsRequest()->PopulateWebServiceWorkerRequest(web_requests[0]);
- web_requests[0].SetBlobDataHandle(
- ExtractBlobHandle(requests.GetAsRequest(), exception_state));
+ request->PopulateWebServiceWorkerRequest(web_requests[0]);
} else if (requests.IsUSVString()) {
Request* request = Request::Create(script_state, requests.GetAsUSVString(),
exception_state);
@@ -430,6 +432,7 @@ Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
return Vector<WebServiceWorkerRequest>();
DCHECK(request);
+ *has_requests_with_body = request->HasBody();
web_requests.resize(1);
request->PopulateWebServiceWorkerRequest(web_requests[0]);
} else {
@@ -475,6 +478,7 @@ void BackgroundFetchManager::DidGetRegistration(
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ case mojom::blink::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED:
// Not applicable for this callback.
break;
}
@@ -526,6 +530,7 @@ void BackgroundFetchManager::DidGetDeveloperIds(
case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ case mojom::blink::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED:
// Not applicable for this callback.
break;
}
@@ -536,15 +541,17 @@ void BackgroundFetchManager::DidGetDeveloperIds(
void BackgroundFetchManager::Trace(blink::Visitor* visitor) {
visitor->Trace(registration_);
visitor->Trace(bridge_);
- visitor->Trace(loader_);
+ visitor->Trace(loaders_);
ContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
void BackgroundFetchManager::ContextDestroyed(ExecutionContext* context) {
- if (loader_) {
- loader_->Stop();
+ for (const auto& loader : loaders_) {
+ if (loader)
+ loader->Stop();
}
+ loaders_.clear();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
index ac445e7d1d0..c850731ac69 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
@@ -67,16 +67,20 @@ class MODULES_EXPORT BackgroundFetchManager final
// Creates a vector of WebServiceWorkerRequest objects for the given set of
// |requests|, which can be either Request objects or URL strings.
+ // |has_requests_with_body| will be set if any of the |requests| has a body.
static Vector<WebServiceWorkerRequest> CreateWebRequestVector(
ScriptState* script_state,
const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
- ExceptionState& exception_state);
+ ExceptionState& exception_state,
+ bool* has_requests_with_body);
void DidLoadIcons(const String& id,
Vector<WebServiceWorkerRequest> web_requests,
mojom::blink::BackgroundFetchOptionsPtr options,
ScriptPromiseResolver* resolver,
- const SkBitmap& icon);
+ BackgroundFetchIconLoader* loader,
+ const SkBitmap& icon,
+ int64_t ideal_to_chosen_icon_size);
void DidFetch(ScriptPromiseResolver* resolver,
base::Time time_started,
mojom::blink::BackgroundFetchError error,
@@ -92,7 +96,7 @@ class MODULES_EXPORT BackgroundFetchManager final
Member<ServiceWorkerRegistration> registration_;
Member<BackgroundFetchBridge> bridge_;
- Member<BackgroundFetchIconLoader> loader_;
+ HeapVector<Member<BackgroundFetchIconLoader>> loaders_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
index 12e59cc0473..cd401cc4bd4 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
@@ -6,9 +6,9 @@
[
Exposed=(Window,Worker),
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchManager {
- [CallWith=ScriptState, RaisesException] Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options);
- [CallWith=ScriptState] Promise<BackgroundFetchRegistration?> get(DOMString id);
- [CallWith=ScriptState] Promise<FrozenArray<DOMString>> getIds();
+ [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchManagerFetch] Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options);
+ [CallWith=ScriptState, MeasureAs=BackgroundFetchManagerGet] Promise<BackgroundFetchRegistration?> get(DOMString id);
+ [CallWith=ScriptState, MeasureAs=BackgroundFetchManagerGetIds] Promise<FrozenArray<DOMString>> getIds();
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
index 063d42f25d4..688658b3fa0 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/blob/blob_data.h"
namespace blink {
@@ -26,8 +25,10 @@ class BackgroundFetchManagerTest : public testing::Test {
Vector<WebServiceWorkerRequest> CreateWebRequestVector(
V8TestingScope& scope,
const RequestOrUSVStringOrRequestOrUSVStringSequence& requests) {
+ bool has_requests_with_body;
return BackgroundFetchManager::CreateWebRequestVector(
- scope.GetScriptState(), requests, scope.GetExceptionState());
+ scope.GetScriptState(), requests, scope.GetExceptionState(),
+ &has_requests_with_body);
}
};
@@ -176,48 +177,4 @@ TEST_F(BackgroundFetchManagerTest, SequenceWithNullValue) {
ESErrorType::kTypeError);
}
-TEST_F(BackgroundFetchManagerTest, BlobsExtracted) {
- V8TestingScope scope;
-
- KURL image_url("https://www.example.com/my_image.png");
- KURL icon_url("https://www.example.com/my_icon.jpg");
-
- // Create first request with a body.
- String body_text = "cat_pic";
- RequestInit request_init;
- request_init.setMethod("POST");
- request_init.setBody(blink::ScriptValue(
- scope.GetScriptState(), ToV8(body_text, scope.GetScriptState())));
- Request* image_request =
- Request::Create(scope.GetScriptState(), image_url.GetString(),
- request_init, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
- ASSERT_TRUE(image_request);
- ASSERT_TRUE(image_request->HasBody());
-
- // Create second request without a body.
- RequestOrUSVString icon_request =
- RequestOrUSVString::FromUSVString(icon_url.GetString());
-
- // Create a request sequence with both requests.
- HeapVector<RequestOrUSVString> request_sequence;
- request_sequence.push_back(RequestOrUSVString::FromRequest(image_request));
- request_sequence.push_back(icon_request);
-
- RequestOrUSVStringOrRequestOrUSVStringSequence requests =
- RequestOrUSVStringOrRequestOrUSVStringSequence::
- FromRequestOrUSVStringSequence(request_sequence);
-
- // Extract the blobs.
- auto web_requests = CreateWebRequestVector(scope, requests);
- ASSERT_FALSE(scope.GetExceptionState().HadException());
-
- ASSERT_EQ(web_requests.size(), 2u);
-
- ASSERT_TRUE(web_requests[0].GetBlobDataHandle());
- EXPECT_EQ(web_requests[0].GetBlobDataHandle()->size(), body_text.length());
-
- EXPECT_FALSE(web_requests[1].GetBlobDataHandle());
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl
index a3e4080f498..bf812380814 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl
@@ -6,7 +6,7 @@
[
Exposed=(ServiceWorker),
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchRecord {
readonly attribute Request request;
[CallWith=ScriptState] readonly attribute Promise<Response> responseReady;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
index bf5b6d9e84c..e425272b6d7 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -30,7 +30,7 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
unsigned long long uploaded,
unsigned long long download_total,
unsigned long long downloaded,
- mojom::BackgroundFetchState state,
+ mojom::BackgroundFetchResult result,
mojom::BackgroundFetchFailureReason failure_reason)
: developer_id_(developer_id),
unique_id_(unique_id),
@@ -38,7 +38,7 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
uploaded_(uploaded),
download_total_(download_total),
downloaded_(downloaded),
- state_(state),
+ result_(result),
failure_reason_(failure_reason),
observer_binding_(this) {}
@@ -51,7 +51,7 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
uploaded_(web_registration.uploaded),
download_total_(web_registration.download_total),
downloaded_(web_registration.downloaded),
- state_(web_registration.state),
+ result_(web_registration.result),
failure_reason_(web_registration.failure_reason),
observer_binding_(this) {
DCHECK(registration);
@@ -74,14 +74,19 @@ void BackgroundFetchRegistration::Initialize(
->AddRegistrationObserver(unique_id_, std::move(observer));
}
-void BackgroundFetchRegistration::OnProgress(uint64_t upload_total,
- uint64_t uploaded,
- uint64_t download_total,
- uint64_t downloaded) {
+void BackgroundFetchRegistration::OnProgress(
+ uint64_t upload_total,
+ uint64_t uploaded,
+ uint64_t download_total,
+ uint64_t downloaded,
+ mojom::BackgroundFetchResult result,
+ mojom::BackgroundFetchFailureReason failure_reason) {
upload_total_ = upload_total;
uploaded_ = uploaded;
download_total_ = download_total;
downloaded_ = downloaded;
+ result_ = result;
+ failure_reason_ = failure_reason;
ExecutionContext* context = GetExecutionContext();
if (!context || context->IsContextDestroyed())
@@ -91,6 +96,10 @@ void BackgroundFetchRegistration::OnProgress(uint64_t upload_total,
DispatchEvent(*Event::Create(EventTypeNames::progress));
}
+void BackgroundFetchRegistration::OnRecordsUnavailable() {
+ records_available_ = false;
+}
+
String BackgroundFetchRegistration::id() const {
return developer_id_;
}
@@ -111,6 +120,10 @@ unsigned long long BackgroundFetchRegistration::downloaded() const {
return downloaded_;
}
+bool BackgroundFetchRegistration::recordsAvailable() const {
+ return records_available_;
+}
+
const AtomicString& BackgroundFetchRegistration::InterfaceName() const {
return EventTargetNames::BackgroundFetchRegistration;
}
@@ -167,29 +180,51 @@ ScriptPromise BackgroundFetchRegistration::MatchImpl(
mojom::blink::QueryParamsPtr cache_query_params,
ExceptionState& exception_state,
bool match_all) {
+ // TODO(crbug.com/875201): Update this check once we support access to active
+ // fetches.
+ if (result_ == mojom::BackgroundFetchResult::UNSET) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(
+ DOMExceptionCode::kInvalidStateError,
+ "Access to records for in-progress background fetches is not yet "
+ "implemented. Please see crbug.com/875201 for more details."));
+ }
+
+ if (!records_available_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(
+ DOMExceptionCode::kInvalidStateError,
+ "The records associated with this background fetch are no longer "
+ "available."));
+ }
+
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
// Convert |request| to WebServiceWorkerRequest.
- base::Optional<WebServiceWorkerRequest> request_to_match;
+ base::Optional<WebServiceWorkerRequest> optional_request;
if (request.has_value()) {
+ WebServiceWorkerRequest request_to_match;
if (request->IsRequest()) {
request->GetAsRequest()->PopulateWebServiceWorkerRequest(
- request_to_match.value());
+ request_to_match);
} else {
Request* new_request = Request::Create(
script_state, request->GetAsUSVString(), exception_state);
if (exception_state.HadException())
return ScriptPromise();
- new_request->PopulateWebServiceWorkerRequest(request_to_match.value());
+ new_request->PopulateWebServiceWorkerRequest(request_to_match);
}
+ optional_request = request_to_match;
}
DCHECK(registration_);
BackgroundFetchBridge::From(registration_)
->MatchRequests(
- developer_id_, unique_id_, request_to_match,
+ developer_id_, unique_id_, optional_request,
std::move(cache_query_params), match_all,
WTF::Bind(&BackgroundFetchRegistration::DidGetMatchingRequests,
WrapPersistent(this), WrapPersistent(resolver), match_all));
@@ -219,6 +254,11 @@ void BackgroundFetchRegistration::DidGetMatchingRequests(
}
if (!return_all) {
+ if (settled_fetches.IsEmpty()) {
+ // Nothing was matched. Resolve with `undefined`.
+ resolver->Resolve();
+ return;
+ }
DCHECK_EQ(settled_fetches.size(), 1u);
DCHECK_EQ(to_return.size(), 1u);
resolver->Resolve(to_return[0]);
@@ -247,6 +287,7 @@ void BackgroundFetchRegistration::DidAbort(
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ case mojom::blink::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED:
// Not applicable for this callback.
break;
}
@@ -254,14 +295,14 @@ void BackgroundFetchRegistration::DidAbort(
NOTREACHED();
}
-const String BackgroundFetchRegistration::state() const {
- switch (state_) {
- case mojom::BackgroundFetchState::SUCCESS:
+const String BackgroundFetchRegistration::result() const {
+ switch (result_) {
+ case mojom::BackgroundFetchResult::SUCCESS:
return "success";
- case mojom::BackgroundFetchState::FAILURE:
+ case mojom::BackgroundFetchResult::FAILURE:
return "failure";
- case mojom::BackgroundFetchState::PENDING:
- return "pending";
+ case mojom::BackgroundFetchResult::UNSET:
+ return "";
}
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
index 4d94efee4b5..bb2adb7c16e 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -39,7 +39,7 @@ class BackgroundFetchRegistration final
unsigned long long uploaded,
unsigned long long download_total,
unsigned long long downloaded,
- mojom::BackgroundFetchState state,
+ mojom::BackgroundFetchResult result,
mojom::BackgroundFetchFailureReason failure_reason);
BackgroundFetchRegistration(
@@ -57,7 +57,10 @@ class BackgroundFetchRegistration final
void OnProgress(uint64_t upload_total,
uint64_t uploaded,
uint64_t download_total,
- uint64_t downloaded) override;
+ uint64_t downloaded,
+ mojom::BackgroundFetchResult result,
+ mojom::BackgroundFetchFailureReason failure_reason) override;
+ void OnRecordsUnavailable() override;
// Web Exposed attribute defined in the IDL file. Corresponds to the
// |developer_id| used elsewhere in the codebase.
@@ -77,7 +80,8 @@ class BackgroundFetchRegistration final
unsigned long long uploaded() const;
unsigned long long downloadTotal() const;
unsigned long long downloaded() const;
- const String state() const;
+ bool recordsAvailable() const;
+ const String result() const;
const String failureReason() const;
const String& unique_id() const { return unique_id_; }
@@ -122,7 +126,8 @@ class BackgroundFetchRegistration final
unsigned long long uploaded_;
unsigned long long download_total_;
unsigned long long downloaded_;
- mojom::BackgroundFetchState state_;
+ bool records_available_ = true;
+ mojom::BackgroundFetchResult result_;
mojom::BackgroundFetchFailureReason failure_reason_;
mojo::Binding<blink::mojom::blink::BackgroundFetchRegistrationObserver>
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
index bb5a4c5bbd6..5760956f4d0 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
@@ -3,8 +3,6 @@
// found in the LICENSE file.
// https://wicg.github.io/background-fetch/#background-fetch-registration
-enum BackgroundFetchState { "pending", "success", "failure" };
-
enum BackgroundFetchFailureReason {
"",
// The operation was aborted by the user, or abort() was called.
@@ -20,24 +18,27 @@ enum BackgroundFetchFailureReason {
"total-download-exceeded"
};
+enum BackgroundFetchResult { "", "success", "failure" };
+
[
Exposed=(Window,Worker),
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchRegistration : EventTarget {
readonly attribute DOMString id;
readonly attribute unsigned long long uploadTotal;
readonly attribute unsigned long long uploaded;
readonly attribute unsigned long long downloadTotal;
readonly attribute unsigned long long downloaded;
- readonly attribute BackgroundFetchState state;
+ readonly attribute BackgroundFetchResult result;
readonly attribute BackgroundFetchFailureReason failureReason;
+ readonly attribute boolean recordsAvailable;
attribute EventHandler onprogress;
- [CallWith=ScriptState] Promise<boolean> abort();
+ [CallWith=ScriptState, MeasureAs=BackgroundFetchRegistrationAbort] Promise<boolean> abort();
// TODO(crbug.com/875201): Change to (Window,Worker) once we support
// match() and matchAll() for active fetches.
- [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options);
- [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
+ [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException, MeasureAs=BackgroundFetchRegistrationMatch] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options);
+ [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException, MeasureAs=BackgroundFetchRegistrationMatchAll] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.idl
index 74090be5ba1..8bee778bbfe 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.idl
@@ -7,7 +7,7 @@
[
Constructor(Request request, Response response),
Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchSettledFetch : BackgroundFetchFetch {
readonly attribute Response? response;
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
index 92b011daf5e..385b64a2999 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
@@ -23,7 +23,7 @@ TypeConverter<blink::BackgroundFetchRegistration*,
mojo_registration->developer_id, mojo_registration->unique_id,
mojo_registration->upload_total, mojo_registration->uploaded,
mojo_registration->download_total, mojo_registration->downloaded,
- mojo_registration->state, mojo_registration->failure_reason);
+ mojo_registration->result, mojo_registration->failure_reason);
}
blink::mojom::blink::BackgroundFetchOptionsPtr TypeConverter<
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
index 20080f5a5c6..824f86a52dd 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
@@ -72,7 +72,8 @@ ScriptPromise BackgroundFetchUpdateUIEvent::updateUI(
ScriptPromise promise = resolver->Promise();
if (ui_options.icons().IsEmpty()) {
- DidGetIcon(resolver, ui_options.title(), SkBitmap());
+ DidGetIcon(resolver, ui_options.title(), SkBitmap(),
+ -1 /* ideal_to_chosen_icon_size */);
} else {
DCHECK(!loader_);
loader_ = new BackgroundFetchIconLoader();
@@ -87,9 +88,11 @@ ScriptPromise BackgroundFetchUpdateUIEvent::updateUI(
return promise;
}
-void BackgroundFetchUpdateUIEvent::DidGetIcon(ScriptPromiseResolver* resolver,
- const String& title,
- const SkBitmap& icon) {
+void BackgroundFetchUpdateUIEvent::DidGetIcon(
+ ScriptPromiseResolver* resolver,
+ const String& title,
+ const SkBitmap& icon,
+ int64_t ideal_to_chosen_icon_size) {
BackgroundFetchBridge::From(service_worker_registration_)
->UpdateUI(registration_->id(), registration_->unique_id(), title, icon,
WTF::Bind(&BackgroundFetchUpdateUIEvent::DidUpdateUI,
@@ -114,6 +117,7 @@ void BackgroundFetchUpdateUIEvent::DidUpdateUI(
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ case mojom::blink::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED:
// Not applicable for this callback.
break;
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
index 81d9e85d77c..e6090c44a29 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
@@ -61,7 +61,8 @@ class MODULES_EXPORT BackgroundFetchUpdateUIEvent final
void DidGetIcon(ScriptPromiseResolver* resolver,
const String& title,
- const SkBitmap& icon);
+ const SkBitmap& icon,
+ int64_t ideal_to_chosen_icon_size);
void DidUpdateUI(ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
index b494c006376..20a3655e666 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
@@ -7,7 +7,7 @@
[
Constructor(DOMString type, BackgroundFetchEventInit init),
Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] interface BackgroundFetchUpdateUIEvent : BackgroundFetchEvent {
[CallWith=ScriptState] Promise<void> updateUI(BackgroundFetchUIOptions options);
}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
index 2f9f6c023e5..7dc81fe2fdb 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
@@ -6,7 +6,7 @@
[
ImplementedAs=ServiceWorkerGlobalScopeBackgroundFetch,
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] partial interface ServiceWorkerGlobalScope {
attribute EventHandler onbackgroundfetchsuccess;
attribute EventHandler onbackgroundfetchfail;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl
index a1d9dee789e..529646b9909 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl
@@ -7,7 +7,7 @@
[
Exposed=(Window,Worker),
ImplementedAs=ServiceWorkerRegistrationBackgroundFetch,
- RuntimeEnabled=BackgroundFetch
+ OriginTrialEnabled=BackgroundFetch
] partial interface ServiceWorkerRegistration {
readonly attribute BackgroundFetchManager backgroundFetch;
};
diff --git a/chromium/third_party/blink/renderer/modules/badging/BUILD.gn b/chromium/third_party/blink/renderer/modules/badging/BUILD.gn
new file mode 100644
index 00000000000..8af60813b49
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/BUILD.gn
@@ -0,0 +1,12 @@
+# 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("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("badging") {
+ sources = [
+ "badge.cc",
+ "badge.h",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/badging/OWNERS b/chromium/third_party/blink/renderer/modules/badging/OWNERS
new file mode 100644
index 00000000000..c8216ae7d7f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/OWNERS
@@ -0,0 +1,5 @@
+estevenson@chromium.org
+mgiuca@chromium.org
+
+# TEAM: apps-dev@chromium.org
+# COMPONENT: Platform>Apps
diff --git a/chromium/third_party/blink/renderer/modules/badging/README.md b/chromium/third_party/blink/renderer/modules/badging/README.md
new file mode 100644
index 00000000000..ad293263220
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/README.md
@@ -0,0 +1,24 @@
+# Badging
+
+This module contains the implementation of the [Badging API]. The implementation
+is under [active development].
+
+[Badging API]: https://github.com/WICG/badging
+[active development]: https://crbug.com/719176
+
+### API
+
+See the [explainer] for details. The Badge interface is a member on Window
+and exposes two static methods:
+
+[explainer]: https://github.com/WICG/badging/blob/master/explainer.md
+
+* `set(contents)`: Sets the associated app's badge as a "flag" (the argument
+ is ignored).
+* `clear()`: Sets the associated app's badge to nothing.
+
+### Testing
+
+`LayoutTests/badging/*.html` tests that the API accepts/rejects the appropriate
+inputs (with a mock Mojo service). Testing at other layers will be added
+during implementation.
diff --git a/chromium/third_party/blink/renderer/modules/badging/badge.cc b/chromium/third_party/blink/renderer/modules/badging/badge.cc
new file mode 100644
index 00000000000..e751f41bb75
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/badge.cc
@@ -0,0 +1,84 @@
+// 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 "third_party/blink/renderer/modules/badging/badge.h"
+
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/renderer/bindings/modules/v8/usv_string_or_long.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+
+namespace blink {
+
+const char Badge::kSupplementName[] = "Badge";
+
+Badge::~Badge() = default;
+
+// static
+Badge* Badge::From(ExecutionContext* context) {
+ Badge* supplement = Supplement<ExecutionContext>::From<Badge>(context);
+ if (!supplement) {
+ supplement = new Badge(context);
+ ProvideTo(*context, supplement);
+ }
+ return supplement;
+}
+
+// static
+void Badge::set(ScriptState* script_state, ExceptionState& exception_state) {
+ BadgeFromState(script_state)->Set(nullptr, exception_state);
+}
+
+// static
+void Badge::set(ScriptState* script_state,
+ USVStringOrLong& contents,
+ ExceptionState& exception_state) {
+ BadgeFromState(script_state)->Set(&contents, exception_state);
+}
+
+// static
+void Badge::clear(ScriptState* script_state) {
+ BadgeFromState(script_state)->Clear();
+}
+
+void Badge::Set(USVStringOrLong* contents, ExceptionState& exception_state) {
+ if (contents) {
+ if (contents->IsLong() && contents->GetAsLong() <= 0) {
+ exception_state.ThrowTypeError("Badge contents should be > 0");
+ return;
+ }
+ if (contents->IsUSVString() && contents->GetAsUSVString() == "") {
+ exception_state.ThrowTypeError(
+ "Badge contents cannot be the empty string");
+ return;
+ }
+ }
+ // TODO(estevenson): Add support for sending badge contents to the browser.
+ // TODO(estevenson): Verify that contents is a single grapheme cluster.
+ badge_service_->SetBadge();
+}
+
+void Badge::Clear() {
+ badge_service_->ClearBadge();
+}
+
+void Badge::Trace(blink::Visitor* visitor) {
+ Supplement<ExecutionContext>::Trace(visitor);
+ ScriptWrappable::Trace(visitor);
+}
+
+Badge::Badge(ExecutionContext* context) {
+ context->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&badge_service_));
+ DCHECK(badge_service_);
+}
+
+// static
+Badge* Badge::BadgeFromState(ScriptState* script_state) {
+ return Badge::From(ExecutionContext::From(script_state));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/badging/badge.h b/chromium/third_party/blink/renderer/modules/badging/badge.h
new file mode 100644
index 00000000000..c6a742a659e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/badge.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 THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
+
+#include "third_party/blink/public/platform/modules/badging/badging.mojom-blink.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class ExceptionState;
+class ExecutionContext;
+class ScriptState;
+class USVStringOrLong;
+
+class Badge final : public ScriptWrappable,
+ public Supplement<ExecutionContext> {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(Badge);
+
+ public:
+ static const char kSupplementName[];
+
+ static Badge* From(ExecutionContext*);
+
+ ~Badge() override;
+
+ // Badge IDL interface.
+ static void set(ScriptState*, ExceptionState&);
+ static void set(ScriptState*, USVStringOrLong&, ExceptionState&);
+ static void clear(ScriptState*);
+
+ void Set(USVStringOrLong*, ExceptionState&);
+ void Clear();
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ explicit Badge(ExecutionContext*);
+
+ static Badge* BadgeFromState(ScriptState* script_state);
+
+ blink::mojom::blink::BadgeServicePtr badge_service_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
diff --git a/chromium/third_party/blink/renderer/modules/badging/badge.idl b/chromium/third_party/blink/renderer/modules/badging/badge.idl
new file mode 100644
index 00000000000..3c5ec519b2d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/badge.idl
@@ -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.
+
+// TODO(estevenson): Add link to spec once complete.
+// https://github.com/WICG/badging/blob/master/explainer.md
+
+[
+ RuntimeEnabled=Badging,
+ // TODO(estevenson): Expose the Badge interface to Worker.
+ Exposed=Window
+] interface Badge {
+ [CallWith=ScriptState, RaisesException]
+ static void set(optional (USVString or long) contents);
+ [CallWith=ScriptState] static void clear();
+};
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
index 7dc24a05041..a5948bf7b64 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
@@ -13,9 +13,9 @@
namespace blink {
BatteryDispatcher& BatteryDispatcher::Instance() {
- DEFINE_STATIC_LOCAL(BatteryDispatcher, battery_dispatcher,
+ DEFINE_STATIC_LOCAL(Persistent<BatteryDispatcher>, battery_dispatcher,
(new BatteryDispatcher));
- return battery_dispatcher;
+ return *battery_dispatcher;
}
BatteryDispatcher::BatteryDispatcher() : has_latest_data_(false) {}
diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
index 81f73d98547..7f4e94f96ce 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
@@ -22,7 +22,7 @@ BatteryManager* BatteryManager::Create(ExecutionContext* context) {
BatteryManager::~BatteryManager() = default;
BatteryManager::BatteryManager(ExecutionContext* context)
- : PausableObject(context), PlatformEventController(ToDocument(context)) {}
+ : PausableObject(context), PlatformEventController(To<Document>(context)) {}
ScriptPromise BatteryManager::StartRequest(ScriptState* script_state) {
if (!battery_property_) {
@@ -68,7 +68,7 @@ void BatteryManager::DidUpdateData() {
return;
}
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
DCHECK(document);
if (document->IsContextPaused() || document->IsContextDestroyed())
return;
diff --git a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
index dca9a1b1b13..3a80ad95c17 100644
--- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
@@ -24,8 +24,8 @@ ScriptPromise NavigatorBattery::getBattery(ScriptState* script_state) {
// Check to see if this request would be blocked according to the Battery
// Status API specification.
- if (context->IsDocument()) {
- LocalFrame* frame = ToDocument(context)->GetFrame();
+ if (auto* document = To<Document>(context)) {
+ LocalFrame* frame = document->GetFrame();
if (frame) {
if (!context->IsSecureContext())
UseCounter::Count(frame, WebFeature::kBatteryStatusInsecureOrigin);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index 5e56ac7ac2f..a875e13ae06 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -167,8 +167,8 @@ ScriptPromise Bluetooth::requestDevice(ScriptState* script_state,
// If the algorithm is not allowed to show a popup, reject promise with a
// SecurityError and abort these steps.
- Document* doc = ToDocumentOrNull(context);
- if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ auto& doc = *To<Document>(context);
+ if (!LocalFrame::HasTransientUserActivation(doc.GetFrame())) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
@@ -176,8 +176,8 @@ ScriptPromise Bluetooth::requestDevice(ScriptState* script_state,
"Must be handling a user gesture to show a permission request."));
}
- if (!service_ && doc) {
- LocalFrame* frame = doc->GetFrame();
+ if (!service_) {
+ LocalFrame* frame = doc.GetFrame();
if (frame) {
frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_));
}
@@ -198,9 +198,7 @@ ScriptPromise Bluetooth::requestDevice(ScriptState* script_state,
return ScriptPromise();
// Record the eTLD+1 of the frame using the API.
- Document* document = ToDocument(context);
- Platform::Current()->RecordRapporURL("Bluetooth.APIUsage.Origin",
- document->Url());
+ Platform::Current()->RecordRapporURL("Bluetooth.APIUsage.Origin", doc.Url());
// Subsequent steps are handled in the browser process.
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
index 6808dec50a9..c5758cd913d 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -26,7 +26,7 @@
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/fetch/response.h"
-#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h"
@@ -169,7 +169,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
class Cache::BarrierCallbackForPut final
: public GarbageCollectedFinalized<BarrierCallbackForPut> {
public:
- BarrierCallbackForPut(int number_of_operations,
+ BarrierCallbackForPut(wtf_size_t number_of_operations,
Cache* cache,
const String& method_name,
ScriptPromiseResolver* resolver)
@@ -181,7 +181,7 @@ class Cache::BarrierCallbackForPut final
batch_operations_.resize(number_of_operations);
}
- void OnSuccess(size_t index,
+ void OnSuccess(wtf_size_t index,
mojom::blink::BatchOperationPtr batch_operation) {
DCHECK_LT(index, batch_operations_.size());
if (!StillActive())
@@ -224,7 +224,7 @@ class Cache::BarrierCallbackForPut final
if (error->message.Contains(
blink::cache_storage::
kDuplicateOperationBaseMessage)) {
- UseCounter::Count(
+ Deprecation::CountDeprecation(
context,
WebFeature::kCacheStorageAddAllSuccessWithDuplicate);
}
@@ -314,7 +314,7 @@ class Cache::BlobHandleCallbackForPut final
USING_GARBAGE_COLLECTED_MIXIN(BlobHandleCallbackForPut);
public:
- BlobHandleCallbackForPut(size_t index,
+ BlobHandleCallbackForPut(wtf_size_t index,
BarrierCallbackForPut* barrier_callback,
Request* request,
Response* response)
@@ -347,7 +347,7 @@ class Cache::BlobHandleCallbackForPut final
}
private:
- const size_t index_;
+ const wtf_size_t index_;
Member<BarrierCallbackForPut> barrier_callback_;
WebServiceWorkerRequest web_request_;
@@ -361,7 +361,7 @@ class Cache::CodeCacheHandleCallbackForPut final
public:
CodeCacheHandleCallbackForPut(ScriptState* script_state,
- size_t index,
+ wtf_size_t index,
BarrierCallbackForPut* barrier_callback,
Request* request,
Response* response)
@@ -432,7 +432,7 @@ class Cache::CodeCacheHandleCallbackForPut final
private:
const Member<ScriptState> script_state_;
- const size_t index_;
+ const wtf_size_t index_;
Member<BarrierCallbackForPut> barrier_callback_;
const String mime_type_;
@@ -708,7 +708,7 @@ ScriptPromise Cache::AddAllImpl(ScriptState* script_state,
request_infos.resize(requests.size());
Vector<ScriptPromise> promises;
promises.resize(requests.size());
- for (size_t i = 0; i < requests.size(); ++i) {
+ for (wtf_size_t i = 0; i < requests.size(); ++i) {
if (!requests[i]->url().ProtocolIsInHTTPFamily()) {
return ScriptPromise::Reject(script_state,
V8ThrowException::CreateTypeError(
@@ -813,7 +813,7 @@ ScriptPromise Cache::PutImpl(ScriptState* script_state,
BarrierCallbackForPut* barrier_callback =
new BarrierCallbackForPut(requests.size(), this, method_name, resolver);
- for (size_t i = 0; i < requests.size(); ++i) {
+ for (wtf_size_t i = 0; i < requests.size(); ++i) {
KURL url(NullURL(), requests[i]->url());
if (!url.ProtocolIsInHTTPFamily()) {
barrier_callback->OnError("Request scheme '" + url.Protocol() +
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 77710ea24af..e3fe6e8fc93 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -14,7 +14,6 @@
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
@@ -214,7 +213,7 @@ class ErrorCacheForTests : public mojom::blink::CacheStorageCache {
if (expected_batch_operations[i]->response) {
ASSERT_EQ(expected_batch_operations[i]->response->url_list.size(),
batch_operations[i]->response->url_list.size());
- for (size_t j = 0;
+ for (wtf_size_t j = 0;
j < expected_batch_operations[i]->response->url_list.size(); ++j) {
EXPECT_EQ(expected_batch_operations[i]->response->url_list[j],
batch_operations[i]->response->url_list[j]);
@@ -516,12 +515,11 @@ TEST_F(CacheStorageTest, BatchOperationArguments) {
Request* request = NewRequestFromUrl(url);
DCHECK(request);
- WebServiceWorkerResponse web_response;
- std::vector<KURL> url_list;
- url_list.push_back(KURL(url));
- web_response.SetURLList(url_list);
- web_response.SetStatusText("OK");
- Response* response = Response::Create(GetScriptState(), web_response);
+ auto fetch_response = mojom::blink::FetchAPIResponse::New();
+ fetch_response->url_list.push_back(KURL(url));
+ fetch_response->response_type = network::mojom::FetchResponseType::kDefault;
+ fetch_response->status_text = String("OK");
+ Response* response = Response::Create(GetScriptState(), *fetch_response);
Vector<mojom::blink::BatchOperationPtr> expected_delete_operations;
{
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
index fac5814cd84..dec003076ee 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -72,7 +73,7 @@ String BuildCacheId(const String& security_origin, const String& cache_name) {
ProtocolResponse ParseCacheId(const String& id,
String* security_origin,
String* cache_name) {
- size_t pipe = id.find('|');
+ wtf_size_t pipe = id.find('|');
if (pipe == WTF::kNotFound)
return ProtocolResponse::Error("Invalid cache id.");
*security_origin = id.Substring(0, pipe);
@@ -189,13 +190,13 @@ struct RequestResponse {
class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> {
public:
- ResponsesAccumulator(int num_responses,
+ ResponsesAccumulator(wtf_size_t num_responses,
const DataRequestParams& params,
mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr,
std::unique_ptr<RequestEntriesCallback> callback)
: params_(params),
num_responses_left_(num_responses),
- responses_(static_cast<size_t>(num_responses)),
+ responses_(num_responses),
cache_ptr_(std::move(cache_ptr)),
callback_(std::move(callback)) {}
@@ -364,7 +365,8 @@ class CachedResponseFileReaderLoaderClient final
void DidFinishLoading() override {
std::unique_ptr<CachedResponse> response =
CachedResponse::create()
- .setBody(Base64Encode(data_->Data(), data_->size()))
+ .setBody(
+ Base64Encode(data_->Data(), SafeCast<unsigned>(data_->size())))
.build();
callback_->sendSuccess(std::move(response));
dispose();
diff --git a/chromium/third_party/blink/renderer/modules/canvas/OWNERS b/chromium/third_party/blink/renderer/modules/canvas/OWNERS
index 99c09426e40..0a9e139f0c3 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/canvas/OWNERS
@@ -2,8 +2,8 @@ fserb@chromium.org
junov@chromium.org
# canvas, imagebitmap
senorblanco@chromium.org
-# OffscreenCanvas
-xlai@chromium.org
+# lowLatency
+mcasas@chromium.org
# TEAM: paint-dev@chromium.org
# COMPONENT: Blink>Canvas
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index 783f5c3e3dd..5bd0cdfee88 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -360,11 +360,8 @@ const Vector<double>& BaseRenderingContext2D::getLineDash() const {
}
static bool LineDashSequenceIsValid(const Vector<double>& dash) {
- for (size_t i = 0; i < dash.size(); i++) {
- if (!std::isfinite(dash[i]) || dash[i] < 0)
- return false;
- }
- return true;
+ return std::all_of(dash.begin(), dash.end(),
+ [](double d) { return std::isfinite(d) && d >= 0; });
}
void BaseRenderingContext2D::setLineDash(const Vector<double>& dash) {
@@ -1794,7 +1791,7 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
// Color / format convert ImageData to context 2D settings if needed. Color /
// format conversion is not needed only if context 2D and ImageData are both
- // in sRGB color space and use 8-8-8-8 pixel storage format. We use RGBA pixel
+ // in sRGB color space and use uint8 pixel storage format. We use RGBA pixel
// order for both ImageData and CanvasResourceProvider, therefore no
// additional swizzling is needed.
CanvasColorParams data_color_params = data->GetCanvasColorParams();
@@ -1802,7 +1799,7 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque);
if (data_color_params.NeedsColorConversion(context_color_params) ||
PixelFormat() == kF16CanvasPixelFormat) {
- unsigned data_length =
+ size_t data_length =
data->Size().Area() * context_color_params.BytesPerPixel();
std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[data_length]);
if (data->ImageDataInCanvasColorSettings(
@@ -1975,9 +1972,8 @@ void BaseRenderingContext2D::CheckOverdraw(
}
float BaseRenderingContext2D::GetFontBaseline(
- const FontMetrics& font_metrics) const {
- return TextMetrics::GetFontBaseline(GetState().GetTextBaseline(),
- font_metrics);
+ const SimpleFontData& font_data) const {
+ return TextMetrics::GetFontBaseline(GetState().GetTextBaseline(), font_data);
}
String BaseRenderingContext2D::textAlign() const {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index a5ba638548a..695f9bc16ad 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -372,7 +372,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
virtual void NeedsFinalizeFrame(){};
- float GetFontBaseline(const FontMetrics&) const;
+ float GetFontBaseline(const SimpleFontData&) const;
static const char kDefaultFont[];
static const char kInheritDirectionString[];
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index 8c7e75769ee..3674c02711f 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -356,7 +356,8 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) {
// We first map canvas coordinates to layout coordinates.
LayoutRect path_rect(bounding_rect);
- IntRect canvas_rect = layout_box->AbsoluteContentBox();
+ LayoutRect canvas_rect = layout_box->PhysicalContentBoxRect();
+ canvas_rect.MoveBy(LayoutPoint(layout_box->LocalToAbsolute()));
path_rect.SetX(
(canvas_rect.X() + path_rect.X() * canvas_rect.Width() / Width()));
path_rect.SetY(
@@ -365,7 +366,7 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) {
path_rect.SetHeight((path_rect.Height() * canvas_rect.Height() / Height()));
// Then we clip the bounding box to the canvas visible range.
- path_rect.Intersect(LayoutRect(canvas_rect));
+ path_rect.Intersect(canvas_rect);
bool is_horizontal_writing_mode =
canvas()->EnsureComputedStyle()->IsHorizontalWritingMode();
@@ -841,7 +842,7 @@ void CanvasRenderingContext2D::DrawTextInternal(
text_run.SetNormalizeSpace(true);
// Draw the item text at the correct point.
FloatPoint location(clampTo<float>(x),
- clampTo<float>(y + GetFontBaseline(font_metrics)));
+ clampTo<float>(y + GetFontBaseline(*font_data)));
double font_width = font.Width(text_run);
bool use_max_width = (max_width && *max_width < font_width);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index ca5ab3b5dda..5a34779343e 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -27,7 +27,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_RENDERING_CONTEXT_2D_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_RENDERING_CONTEXT_2D_H_
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
@@ -40,6 +39,7 @@
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace cc {
@@ -195,6 +195,8 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void Trace(blink::Visitor*) override;
+ CanvasColorParams ColorParamsForTest() const { return ColorParams(); };
+
protected:
void NeedsFinalizeFrame() override {
CanvasRenderingContext::NeedsFinalizeFrame();
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
index 6e0b7cec601..fee85211f2b 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
@@ -23,7 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasrenderingcontext2d
+// https://html.spec.whatwg.org/multipage/canvas.html#canvasrenderingcontext2d
// The spec specifies:
// typedef (HTMLImageElement or
@@ -77,7 +77,7 @@ interface CanvasRenderingContext2D {
attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
[RaisesException] CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
- [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=NullString] DOMString repetitionType);
+ [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetitionType);
// shadows
attribute unrestricted double shadowOffsetX;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
index 268f1b3060c..93c38d72a27 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl
@@ -8,6 +8,6 @@
dictionary CanvasRenderingContext2DSettings {
boolean alpha = true;
[RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb";
- [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "8-8-8-8";
+ [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8";
};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
index ff04d8d5ec3..c71b69a3b18 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -155,8 +155,8 @@ void CanvasRenderingContext2DState::SetLineDash(const Vector<double>& dash) {
}
static bool HasANonZeroElement(const Vector<double>& line_dash) {
- for (size_t i = 0; i < line_dash.size(); i++) {
- if (line_dash[i] != 0.0)
+ for (double dash : line_dash) {
+ if (dash != 0.0)
return true;
}
return false;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index 896ba70a40e..a1cb3e79b7c 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -16,9 +16,11 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
+#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h"
@@ -34,11 +36,12 @@
#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
+#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/skia/include/core/SkColorSpaceXform.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"
-#include "third_party/skia/include/core/SkSwizzle.h"
+#include "third_party/skia/third_party/skcms/skcms.h"
using testing::_;
using testing::InSequence;
@@ -233,7 +236,8 @@ void CanvasRenderingContext2DTest::SetUp() {
StringOrCanvasGradientOrCanvasPattern wrapped_alpha_gradient;
this->AlphaGradient().SetCanvasGradient(alpha_gradient);
- global_memory_cache_ = ReplaceMemoryCacheForTesting(MemoryCache::Create());
+ global_memory_cache_ = ReplaceMemoryCacheForTesting(MemoryCache::Create(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
}
void CanvasRenderingContext2DTest::TearDown() {
@@ -278,6 +282,30 @@ class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge {
//============================================================================
+class FakeCanvasResourceProvider : public CanvasResourceProvider {
+ public:
+ FakeCanvasResourceProvider(const IntSize& size,
+ CanvasColorParams color_params,
+ AccelerationHint hint)
+ : CanvasResourceProvider(size, color_params, nullptr, nullptr),
+ is_accelerated_(hint != kPreferNoAcceleration) {}
+ ~FakeCanvasResourceProvider() override = default;
+ bool IsAccelerated() const override { return is_accelerated_; }
+ scoped_refptr<CanvasResource> ProduceFrame() override {
+ return scoped_refptr<CanvasResource>();
+ }
+ bool SupportsDirectCompositing() const override { return false; }
+ bool IsValid() const override { return false; }
+ sk_sp<SkSurface> CreateSkSurface() const override {
+ return sk_sp<SkSurface>();
+ }
+
+ private:
+ bool is_accelerated_;
+};
+
+//============================================================================
+
class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge {
public:
MockImageBufferSurfaceForOverwriteTesting(const IntSize& size,
@@ -297,8 +325,8 @@ class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge {
std::make_unique<MockImageBufferSurfaceForOverwriteTesting>( \
size, CanvasColorParams()); \
MockImageBufferSurfaceForOverwriteTesting* surface_ptr = mock_surface.get(); \
- CanvasElement().SetCanvas2DLayerBridgeForTesting(std::move(mock_surface), \
- size); \
+ CanvasElement().SetResourceProviderForTesting( \
+ nullptr, std::move(mock_surface), size); \
EXPECT_CALL(*surface_ptr, WillOverwriteCanvas()).Times(EXPECTED_OVERDRAWS); \
Context2d()->save();
@@ -546,13 +574,17 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
CreateContext(kNonOpaque);
IntSize size(10, 10);
- std::unique_ptr<FakeCanvas2DLayerBridge> fake_accelerate_surface =
+ std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider =
+ std::make_unique<FakeCanvasResourceProvider>(size, CanvasColorParams(),
+ kPreferAcceleration);
+ std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge =
std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(),
kPreferAcceleration);
- FakeCanvas2DLayerBridge* fake_accelerate_surface_ptr =
- fake_accelerate_surface.get();
- CanvasElement().SetCanvas2DLayerBridgeForTesting(
- std::move(fake_accelerate_surface), size);
+ FakeCanvas2DLayerBridge* fake_2d_layer_bridge_ptr =
+ fake_2d_layer_bridge.get();
+ CanvasElement().SetResourceProviderForTesting(
+ std::move(fake_resource_provider), std::move(fake_2d_layer_bridge), size);
+
// 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per
// pixel per buffer, and 2 is an estimate of num of gpu buffers required
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
@@ -560,14 +592,14 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
// Switching accelerated mode to non-accelerated mode
- fake_accelerate_surface_ptr->SetIsAccelerated(false);
+ fake_2d_layer_bridge_ptr->SetIsAccelerated(false);
CanvasElement().UpdateMemoryUsage();
EXPECT_EQ(0, GetCurrentGPUMemoryUsage());
EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
// Switching non-accelerated mode to accelerated mode
- fake_accelerate_surface_ptr->SetIsAccelerated(true);
+ fake_2d_layer_bridge_ptr->SetIsAccelerated(true);
CanvasElement().UpdateMemoryUsage();
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(800, GetGlobalGPUMemoryUsage());
@@ -579,17 +611,22 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
CanvasContextCreationAttributesCore attributes;
anotherCanvas->GetCanvasRenderingContext("2d", attributes);
IntSize size2(10, 5);
- auto fake_accelerate_surface2 = std::make_unique<FakeCanvas2DLayerBridge>(
- size2, CanvasColorParams(), kPreferAcceleration);
- anotherCanvas->SetCanvas2DLayerBridgeForTesting(
- std::move(fake_accelerate_surface2), size2);
+ std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge2 =
+ std::make_unique<FakeCanvas2DLayerBridge>(size2, CanvasColorParams(),
+ kPreferAcceleration);
+ std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider2 =
+ std::make_unique<FakeCanvasResourceProvider>(size2, CanvasColorParams(),
+ kPreferAcceleration);
+ anotherCanvas->SetResourceProviderForTesting(
+ std::move(fake_resource_provider2), std::move(fake_2d_layer_bridge2),
+ size2);
EXPECT_EQ(800, GetCurrentGPUMemoryUsage());
EXPECT_EQ(1200, GetGlobalGPUMemoryUsage());
EXPECT_EQ(2u, GetGlobalAcceleratedContextCount());
// Tear down the first image buffer that resides in current canvas element
CanvasElement().SetSize(IntSize(20, 20));
- Mock::VerifyAndClearExpectations(fake_accelerate_surface_ptr);
+ Mock::VerifyAndClearExpectations(fake_2d_layer_bridge_ptr);
EXPECT_EQ(400, GetGlobalGPUMemoryUsage());
EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
@@ -634,7 +671,8 @@ TEST_F(CanvasRenderingContext2DTest, MAYBE_GetImageDataDisablesAcceleration) {
IntSize size(300, 300);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(size, Canvas2DLayerBridge::kForceAccelerationForTesting);
- CanvasElement().SetCanvas2DLayerBridgeForTesting(std::move(bridge), size);
+ CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
+ size);
DrawSomething(); // Lock-in gpu acceleration
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
@@ -668,63 +706,6 @@ TEST_F(CanvasRenderingContext2DTest, MAYBE_GetImageDataDisablesAcceleration) {
}
}
-TEST_F(CanvasRenderingContext2DTest, TextureUploadHeuristics) {
- ScopedCanvas2dFixedRenderingModeForTest canvas_2d_fixed_rendering_mode(false);
-
- enum TestVariants {
- kLargeTextureDisablesAcceleration = 0,
- kSmallTextureDoesNotDisableAcceleration = 1,
-
- kTestVariantCount = 2,
- };
-
- for (int test_variant = 0; test_variant < kTestVariantCount; test_variant++) {
- int delta = test_variant == kLargeTextureDisablesAcceleration ? 1 : -1;
- int src_size =
- std::sqrt(static_cast<float>(
- CanvasHeuristicParameters::kDrawImageTextureUploadSoftSizeLimit)) +
- delta;
- int dst_size =
- src_size /
- std::sqrt(static_cast<float>(
- CanvasHeuristicParameters::
- kDrawImageTextureUploadSoftSizeLimitScaleThreshold)) -
- delta;
-
- CreateContext(kNonOpaque);
- IntSize size(dst_size, dst_size);
- std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration);
- CanvasElement().SetCanvas2DLayerBridgeForTesting(std::move(bridge), size);
-
- EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
- // 4 bytes per pixel * 2 buffers = 8
- EXPECT_EQ(8 * dst_size * dst_size, GetGlobalGPUMemoryUsage());
- sk_sp<SkSurface> sk_surface =
- SkSurface::MakeRasterN32Premul(src_size, src_size);
- scoped_refptr<StaticBitmapImage> big_bitmap =
- StaticBitmapImage::Create(sk_surface->makeImageSnapshot());
- ASSERT_TRUE(big_bitmap);
- ImageBitmap* big_image = ImageBitmap::Create(std::move(big_bitmap));
- NonThrowableExceptionState exception_state;
- V8TestingScope scope;
- Context2d()->drawImage(scope.GetScriptState(), big_image, 0, 0, src_size,
- src_size, 0, 0, dst_size, dst_size, exception_state);
- EXPECT_FALSE(exception_state.HadException());
-
- if (test_variant == kLargeTextureDisablesAcceleration) {
- EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
- EXPECT_EQ(0u, GetGlobalAcceleratedContextCount());
- EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
- } else {
- EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
- EXPECT_EQ(1u, GetGlobalAcceleratedContextCount());
- EXPECT_EQ(8 * dst_size * dst_size, GetGlobalGPUMemoryUsage());
- }
- }
-}
-
TEST_F(CanvasRenderingContext2DTest,
NoResourceProviderInCanvas2DBufferInitialization) {
// This test enforces that there is no eager creation of
@@ -737,21 +718,22 @@ TEST_F(CanvasRenderingContext2DTest,
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferAcceleration);
- CanvasElement().SetCanvas2DLayerBridgeForTesting(
- std::move(fake_accelerate_surface), size);
+ CanvasElement().SetResourceProviderForTesting(
+ nullptr, std::move(fake_accelerate_surface), size);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge());
EXPECT_FALSE(CanvasElement().ResourceProvider());
}
-TEST_F(CanvasRenderingContext2DTest, DisableAcceleration_UpdateGPUMemoryUsage) {
+TEST_F(CanvasRenderingContext2DTest,
+ DISABLED_DisableAcceleration_UpdateGPUMemoryUsage) {
CreateContext(kNonOpaque);
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferAcceleration);
- CanvasElement().SetCanvas2DLayerBridgeForTesting(
- std::move(fake_accelerate_surface), size);
+ CanvasElement().SetResourceProviderForTesting(
+ nullptr, std::move(fake_accelerate_surface), size);
CanvasRenderingContext2D* context = Context2d();
// 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per
@@ -783,8 +765,8 @@ TEST_F(CanvasRenderingContext2DTest,
IntSize size(10, 10);
auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
size, CanvasColorParams(), kPreferAcceleration);
- CanvasElement().SetCanvas2DLayerBridgeForTesting(
- std::move(fake_accelerate_surface), size);
+ CanvasElement().SetResourceProviderForTesting(
+ nullptr, std::move(fake_accelerate_surface), size);
FakeCanvasResourceHost host(size);
auto fake_deaccelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>(
@@ -811,27 +793,111 @@ TEST_F(CanvasRenderingContext2DTest,
Mock::VerifyAndClearExpectations(surface_ptr);
}
-enum class ColorSpaceConversion : uint8_t {
- NONE = 0,
- DEFAULT_COLOR_CORRECTED = 1,
- SRGB = 2,
- LINEAR_RGB = 3,
- P3 = 4,
- REC2020 = 5,
+static void TestDrawSingleHighBitDepthPNGOnCanvas(
+ String filepath,
+ CanvasRenderingContext2D* context,
+ Document& document,
+ ScriptState* script_state) {
+ scoped_refptr<SharedBuffer> pixel_buffer = test::ReadFromFile(filepath);
+ ASSERT_EQ(false, pixel_buffer->IsEmpty());
+
+ ImageResourceContent* resource_content =
+ ImageResourceContent::CreateNotStarted();
+ const bool all_data_received = true;
+ const bool is_multipart = false;
+ ImageResourceContent::UpdateImageResult update_result =
+ resource_content->UpdateImage(
+ pixel_buffer, ResourceStatus::kPending,
+ ImageResourceContent::UpdateImageOption::kUpdateImage,
+ all_data_received, is_multipart);
+ ASSERT_EQ(ImageResourceContent::UpdateImageResult::kNoDecodeError,
+ update_result);
+
+ HTMLImageElement* image_element = HTMLImageElement::Create(document);
+ image_element->SetImageForTest(resource_content);
+
+ context->clearRect(0, 0, 2, 2);
+ NonThrowableExceptionState exception_state;
+ CanvasImageSourceUnion image_union;
+ image_union.SetHTMLImageElement(image_element);
+ context->drawImage(script_state, image_union, 0, 0, exception_state);
+
+ ImageData* image_data = context->getImageData(0, 0, 2, 2, exception_state);
+ ImageDataArray data_array = image_data->dataUnion();
+ ASSERT_TRUE(data_array.IsFloat32Array());
+ DOMArrayBufferView* buffer_view = data_array.GetAsFloat32Array().View();
+ ASSERT_EQ(16u, buffer_view->byteLength() / buffer_view->TypeSize());
+ float* actual_pixels = static_cast<float*>(buffer_view->BaseAddress());
+
+ sk_sp<SkImage> decoded_image =
+ resource_content->GetImage()->PaintImageForCurrentFrame().GetSkImage();
+ ASSERT_EQ(kRGBA_F16_SkColorType, decoded_image->colorType());
+ sk_sp<SkImage> color_converted_image = decoded_image->makeColorSpace(
+ context->ColorParamsForTest().GetSkColorSpaceForSkSurfaces());
+ float expected_pixels[16];
+ SkImageInfo expected_info_no_color_space = SkImageInfo::Make(
+ 2, 2, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, nullptr);
+ color_converted_image->readPixels(
+ expected_info_no_color_space, expected_pixels,
+ expected_info_no_color_space.minRowBytes(), 0, 0);
+ ColorCorrectionTestUtils::CompareColorCorrectedPixels(
+ actual_pixels, expected_pixels, 4, kPixelFormat_ffff);
+}
+
+static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
+ String canvas_color_space,
+ Document& document,
+ Persistent<HTMLCanvasElement> canvas,
+ ScriptState* script_state) {
+ // Prepare the wide gamut context with the given color space.
+ CanvasContextCreationAttributesCore attributes;
+ attributes.alpha = true;
+ attributes.color_space = canvas_color_space;
+ attributes.pixel_format = "float16";
+ CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(
+ canvas->GetCanvasRenderingContext("2d", attributes));
- LAST = REC2020
-};
+ // Prepare the png file path and call the test routine
+ std::vector<String> interlace_status = {"", "_interlaced"};
+ std::vector<String> color_profiles = {"_sRGB", "_e-sRGB", "_AdobeRGB",
+ "_DisplayP3", "_ProPhoto", "_Rec2020"};
+ std::vector<String> alpha_status = {"_opaque", "_transparent"};
+
+ String path = test::CoreTestDataPath();
+ path.append("/png-16bit/");
+ for (auto interlace : interlace_status) {
+ for (auto color_profile : color_profiles) {
+ for (auto alpha : alpha_status) {
+ String filename = "2x2_16bit";
+ filename.append(interlace);
+ filename.append(color_profile);
+ filename.append(alpha);
+ filename.append(".png");
+ String full_path = path;
+ full_path.append(filename);
+ TestDrawSingleHighBitDepthPNGOnCanvas(full_path, context, document,
+ script_state);
+ }
+ }
+ }
+}
+
+TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnLinearRGBCanvas) {
+ TestDrawHighBitDepthPNGsOnWideGamutCanvas(
+ "linear-rgb", GetDocument(),
+ Persistent<HTMLCanvasElement>(CanvasElement()), GetScriptState());
+}
-static ImageBitmapOptions PrepareBitmapOptionsAndSetRuntimeFlags(
- const ColorSpaceConversion& color_space_conversion) {
- // Set the color space conversion in ImageBitmapOptions
- ImageBitmapOptions options;
- static const Vector<String> kConversions = {
- "none", "default", "srgb", "linear-rgb", "p3", "rec2020"};
- options.setColorSpaceConversion(
- kConversions[static_cast<uint8_t>(color_space_conversion)]);
+TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) {
+ TestDrawHighBitDepthPNGsOnWideGamutCanvas(
+ "p3", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()),
+ GetScriptState());
+}
- return options;
+TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) {
+ TestDrawHighBitDepthPNGsOnWideGamutCanvas(
+ "rec2020", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()),
+ GetScriptState());
}
TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
@@ -845,89 +911,62 @@ TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
StringOrCanvasGradientOrCanvasPattern fill_style;
fill_style.SetString("#FFC08040"); // 255,192,128,64
context->setFillStyle(fill_style);
- context->fillRect(0, 0, 4, 4);
- NonThrowableExceptionState exception_state;
- uint8_t* src_pixel =
- context->getImageData(2, 2, 1, 1, exception_state)->data()->Data();
+ context->fillRect(0, 0, 1, 1);
+ scoped_refptr<StaticBitmapImage> snapshot =
+ canvas->Snapshot(kFrontBuffer, kPreferNoAcceleration);
+ ASSERT_TRUE(snapshot);
+ sk_sp<SkImage> source_image =
+ snapshot->PaintImageForCurrentFrame().GetSkImage();
+ SkPixmap source_pixmap;
+ source_image->peekPixels(&source_pixmap);
// Create and test the ImageBitmap objects.
- base::Optional<IntRect> crop_rect = IntRect(0, 0, 4, 4);
- sk_sp<SkColorSpace> color_space = nullptr;
- SkColorType color_type = SkColorType::kRGBA_8888_SkColorType;
- SkColorSpaceXform::ColorFormat color_format32 =
- SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
- SkColorSpaceXform::ColorFormat color_format = color_format32;
- sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
-
- for (uint8_t i =
- static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
- i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
- ColorSpaceConversion color_space_conversion =
- static_cast<ColorSpaceConversion>(i);
-
- switch (color_space_conversion) {
- case ColorSpaceConversion::NONE:
- NOTREACHED();
- break;
- case ColorSpaceConversion::DEFAULT_COLOR_CORRECTED:
- case ColorSpaceConversion::SRGB:
- color_space = SkColorSpace::MakeSRGB();
- color_format = color_format32;
- break;
- case ColorSpaceConversion::LINEAR_RGB:
- color_space = SkColorSpace::MakeSRGBLinear();
- color_type = SkColorType::kRGBA_F16_SkColorType;
- color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
- break;
- case ColorSpaceConversion::P3:
- color_space =
- SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
- SkColorSpace::kDCIP3_D65_Gamut);
- color_type = SkColorType::kRGBA_F16_SkColorType;
- color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
- break;
- case ColorSpaceConversion::REC2020:
- color_space =
- SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
- SkColorSpace::kRec2020_Gamut);
- color_type = SkColorType::kRGBA_F16_SkColorType;
- color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
- break;
- default:
- NOTREACHED();
- }
-
+ base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1);
+ for (int conversion_iterator = kColorSpaceConversion_Default;
+ conversion_iterator <= kColorSpaceConversion_Last;
+ conversion_iterator++) {
// Color convert using ImageBitmap
- ImageBitmapOptions options =
- PrepareBitmapOptionsAndSetRuntimeFlags(color_space_conversion);
+ ImageBitmapOptions options;
+ options.setColorSpaceConversion(
+ ColorCorrectionTestUtils::ColorSpaceConversionToString(
+ static_cast<ColorSpaceConversion>(conversion_iterator)));
ImageBitmap* image_bitmap = ImageBitmap::Create(canvas, crop_rect, options);
ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> converted_image =
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
ASSERT_TRUE(converted_image);
- SkImageInfo image_info =
- SkImageInfo::Make(1, 1, color_type, SkAlphaType::kUnpremul_SkAlphaType,
- converted_image->refColorSpace());
- std::unique_ptr<uint8_t[]> converted_pixel(
- new uint8_t[image_info.bytesPerPixel()]());
- EXPECT_TRUE(converted_image->readPixels(image_info, converted_pixel.get(),
- image_info.minRowBytes(), 2, 2));
-
- // Transform the source pixel and check if the image bitmap color conversion
- // is done correctly.
- std::unique_ptr<SkColorSpaceXform> color_space_xform =
- SkColorSpaceXform::New(src_rgb_color_space.get(), color_space.get());
- std::unique_ptr<uint8_t[]> transformed_pixel(
- new uint8_t[image_info.bytesPerPixel()]());
- EXPECT_TRUE(color_space_xform->apply(color_format, transformed_pixel.get(),
- color_format32, src_pixel, 1,
- SkAlphaType::kUnpremul_SkAlphaType));
+ SkPixmap converted_pixmap;
+ converted_image->peekPixels(&converted_pixmap);
+
+ // Manual color convert for testing
+ sk_sp<SkColorSpace> color_space =
+ ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
+ static_cast<ColorSpaceConversion>(conversion_iterator));
+ if (conversion_iterator == kColorSpaceConversion_Preserve)
+ color_space = SkColorSpace::MakeSRGB();
+
+ // TODO: crbug.com/768855: Remove if statement when CanvasResourceProvider
+ // does not use SkColorSpaceXformCanvas (which rips off sRGB from
+ // ImageBitmap).
+ if (!color_space->isSRGB()) {
+ EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
+ converted_image->colorSpace()));
+ }
+
+ SkColorType color_type = SkColorType::kN32_SkColorType;
+ if (color_space && color_space->gammaIsLinear())
+ color_type = kRGBA_F16_SkColorType;
+ SkImageInfo image_info = SkImageInfo::Make(
+ 1, 1, color_type, SkAlphaType::kPremul_SkAlphaType, color_space);
+ SkBitmap manual_converted_bitmap;
+ EXPECT_TRUE(manual_converted_bitmap.tryAllocPixels(image_info));
+ source_pixmap.readPixels(manual_converted_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels(
- converted_pixel.get(), transformed_pixel.get(), 1,
- (color_type == kRGBA_8888_SkColorType) ? kUint8ClampedArrayStorageFormat
- : kUint16ArrayStorageFormat,
- kAlphaUnmultiplied, kUnpremulRoundTripTolerance);
+ converted_pixmap.addr(), manual_converted_bitmap.pixmap().addr(), 1,
+ (color_type == kN32_SkColorType) ? kPixelFormat_8888
+ : kPixelFormat_hhhh,
+ kAlphaMultiplied, kNoUnpremulRoundTripTolerance);
}
}
@@ -1050,8 +1089,7 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
data_array->BaseAddress(), data_length,
image_data_color_spaces[i], image_data_storage_formats[j],
canvas_color_spaces[k], canvas_pixel_formats[k],
- pixels_converted_manually,
- SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat));
+ pixels_converted_manually, kPixelFormat_ffff));
// Create a canvas and call putImageData and getImageData to make sure
// the conversion is done correctly.
@@ -1073,8 +1111,8 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
pixels_from_get_image_data, pixels_converted_manually.get(),
num_pixels,
(canvas_pixel_formats[k] == kRGBA8CanvasPixelFormat)
- ? kUint8ClampedArrayStorageFormat
- : kFloat32ArrayStorageFormat,
+ ? kPixelFormat_8888
+ : kPixelFormat_ffff,
kAlphaUnmultiplied, kUnpremulRoundTripTolerance);
}
}
@@ -1132,7 +1170,8 @@ TEST_F(CanvasRenderingContext2DTestWithTestingPlatform,
MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration);
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
- CanvasElement().SetCanvas2DLayerBridgeForTesting(std::move(bridge), size);
+ CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
+ size);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
// Take a snapshot to trigger lazy resource provider creation
@@ -1174,7 +1213,8 @@ TEST_F(CanvasRenderingContext2DTestWithTestingPlatform,
MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration);
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
- CanvasElement().SetCanvas2DLayerBridgeForTesting(std::move(bridge), size);
+ CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
+ size);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
index 7b655dd12a7..98875e974f5 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
@@ -22,7 +22,7 @@
// N.B.: Web IDL doesn't support multiple inheritance of dictionaries.
enum CanvasPixelFormat {
- "8-8-8-8", // default
+ "uint8", // default
"10-10-10-2",
"12-12-12-12",
"float16",
@@ -39,7 +39,7 @@ dictionary CanvasContextCreationAttributesModule {
// Canvas 2D attributes
boolean alpha = true; // Also used for WebGL.
[RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb";
- [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "8-8-8-8";
+ [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8";
// WebGL attributes
boolean depth = true;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
index dfa1d902e3e..cded2b9122e 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
@@ -18,7 +18,7 @@ void HTMLCanvasElementModule::getContext(
const CanvasContextCreationAttributesModule& attributes,
ExceptionState& exception_state,
RenderingContext& result) {
- if (canvas.SurfaceLayerBridge()) {
+ if (canvas.SurfaceLayerBridge() && !canvas.LowLatencyEnabled()) {
// The existence of canvas surfaceLayerBridge indicates that
// HTMLCanvasElement.transferControlToOffscreen() has been called.
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -30,9 +30,8 @@ void HTMLCanvasElementModule::getContext(
CanvasRenderingContext* context = canvas.GetCanvasRenderingContext(
type, ToCanvasContextCreationAttributes(attributes));
- if (context) {
+ if (context)
context->SetCanvasGetContextResult(result);
- }
}
OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen(
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
index 87c5826c214..121b82b5c80 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
@@ -5,17 +5,46 @@
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h"
#include <memory>
+
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
+#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h"
+#include "third_party/blink/renderer/platform/graphics/test/mock_embedded_frame_sink_provider.h"
+
+using ::testing::_;
+using ::testing::Values;
namespace blink {
-class HTMLCanvasElementModuleTest : public PageTestBase {
+namespace {
+
+// This class allows for overriding GenerateFrameSinkId() so that the
+// HTMLCanvasElement's SurfaceLayerBridge will get a syntactically correct
+// FrameSinkId.
+class TestingPlatformSupportWithGenerateFrameSinkId
+ : public TestingPlatformSupport {
+ public:
+ viz::FrameSinkId GenerateFrameSinkId() override {
+ // Doesn't matter what we return as long as is not zero.
+ constexpr uint32_t kClientId = 2;
+ constexpr uint32_t kSinkId = 1;
+ return viz::FrameSinkId(kClientId, kSinkId);
+ }
+};
+
+} // unnamed namespace
+
+class HTMLCanvasElementModuleTest : public PageTestBase,
+ public ::testing::WithParamInterface<bool> {
protected:
void SetUp() override {
PageTestBase::SetUp();
@@ -23,28 +52,83 @@ class HTMLCanvasElementModuleTest : public PageTestBase {
canvas_element_ = ToHTMLCanvasElement(GetElementById("c"));
}
- HTMLCanvasElement& CanvasElement() const { return *canvas_element_; }
- OffscreenCanvas* TransferControlToOffscreen(ExceptionState&);
+ HTMLCanvasElement& canvas_element() const { return *canvas_element_; }
+ OffscreenCanvas* TransferControlToOffscreen(ExceptionState& exception_state) {
+ return HTMLCanvasElementModule::TransferControlToOffscreenInternal(
+ canvas_element(), exception_state);
+ }
- private:
Persistent<HTMLCanvasElement> canvas_element_;
+ Persistent<CanvasRenderingContext> context_;
};
-OffscreenCanvas* HTMLCanvasElementModuleTest::TransferControlToOffscreen(
- ExceptionState& exception_state) {
- // This unit test only tests if the Canvas Id is associated correctly, so we
- // exclude the part that creates surface layer bridge because a mojo message
- // pipe cannot be tested using webkit unit tests.
- return HTMLCanvasElementModule::TransferControlToOffscreenInternal(
- CanvasElement(), exception_state);
-}
-
+// Tests if the Canvas Id is associated correctly.
TEST_F(HTMLCanvasElementModuleTest, TransferControlToOffscreen) {
NonThrowableExceptionState exception_state;
- OffscreenCanvas* offscreen_canvas =
+ const OffscreenCanvas* offscreen_canvas =
TransferControlToOffscreen(exception_state);
- DOMNodeId canvas_id = offscreen_canvas->PlaceholderCanvasId();
- EXPECT_EQ(canvas_id, DOMNodeIds::IdForNode(&(CanvasElement())));
+ const DOMNodeId canvas_id = offscreen_canvas->PlaceholderCanvasId();
+ EXPECT_EQ(canvas_id, DOMNodeIds::IdForNode(&(canvas_element())));
+}
+
+// Verifies that a lowLatency canvas has the appropriate opacity/blending
+// information sent to the CompositorFrameSink.
+TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) {
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithGenerateFrameSinkId>
+ platform;
+
+ // To intercept SubmitCompositorFrame/SubmitCompositorFrameSync messages sent
+ // by a canvas's CanvasResourceDispatcher, we have to override the Mojo
+ // EmbeddedFrameSinkProvider interface impl and its CompositorFrameSinkClient.
+ MockEmbeddedFrameSinkProvider mock_embedded_frame_sink_provider;
+ mojo::Binding<mojom::blink::EmbeddedFrameSinkProvider>
+ embedded_frame_sink_provider_binding(&mock_embedded_frame_sink_provider);
+ auto override =
+ mock_embedded_frame_sink_provider.CreateScopedOverrideMojoInterface(
+ &embedded_frame_sink_provider_binding);
+
+ const bool context_alpha = GetParam();
+ CanvasContextCreationAttributesCore attrs;
+ attrs.alpha = context_alpha;
+ attrs.low_latency = true;
+ // |context_| creation triggers a SurfaceLayerBridge creation which connects
+ // to a MockEmbeddedFrameSinkProvider to create a new CompositorFrameSink,
+ // that will receive a SetNeedsBeginFrame() upon construction.
+ mock_embedded_frame_sink_provider
+ .set_num_expected_set_needs_begin_frame_on_sink_construction(1);
+ EXPECT_CALL(mock_embedded_frame_sink_provider, CreateCompositorFrameSink_(_));
+ context_ = canvas_element().GetCanvasRenderingContext(String("2d"), attrs);
+ EXPECT_EQ(context_->CreationAttributes().alpha, attrs.alpha);
+ EXPECT_TRUE(context_->CreationAttributes().low_latency);
+ EXPECT_TRUE(canvas_element().LowLatencyEnabled());
+ EXPECT_TRUE(canvas_element().SurfaceLayerBridge());
+ platform->RunUntilIdle();
+
+ // This call simulates having drawn something before FinalizeFrame().
+ canvas_element().DidDraw();
+
+ ::testing::InSequence s;
+ EXPECT_CALL(mock_embedded_frame_sink_provider.mock_compositor_frame_sink(),
+ DidAllocateSharedBitmap(_, _));
+ EXPECT_CALL(mock_embedded_frame_sink_provider.mock_compositor_frame_sink(),
+ SubmitCompositorFrame_(_))
+ .WillOnce(::testing::WithArg<0>(
+ ::testing::Invoke([context_alpha](const viz::CompositorFrame* frame) {
+ ASSERT_EQ(frame->render_pass_list.size(), 1u);
+
+ const auto& quad_list = frame->render_pass_list[0]->quad_list;
+ ASSERT_EQ(quad_list.size(), 1u);
+ EXPECT_EQ(quad_list.front()->needs_blending, context_alpha);
+
+ const auto& shared_quad_state_list =
+ frame->render_pass_list[0]->shared_quad_state_list;
+ ASSERT_EQ(shared_quad_state_list.size(), 1u);
+ EXPECT_NE(shared_quad_state_list.front()->are_contents_opaque,
+ context_alpha);
+ })));
+ canvas_element().FinalizeFrame();
+ platform->RunUntilIdle();
}
+INSTANTIATE_TEST_CASE_P(, HTMLCanvasElementModuleTest, Values(true, false));
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
index d1e3db9986c..061ca895e20 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.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 "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
+
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h"
@@ -9,43 +11,50 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
-#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h"
#include "third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
+#include "third_party/blink/renderer/platform/graphics/test/mock_compositor_frame_sink.h"
+#include "third_party/blink/renderer/platform/graphics/test/mock_embedded_frame_sink_provider.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
-using testing::Mock;
+using ::testing::_;
+using ::testing::Combine;
+using ::testing::ValuesIn;
namespace blink {
-class OffscreenCanvasTest : public PageTestBase {
+namespace {
+constexpr uint32_t kClientId = 2;
+constexpr uint32_t kSinkId = 1;
+
+struct TestParams {
+ bool alpha;
+ bool low_latency;
+};
+} // unnamed namespace
+
+class OffscreenCanvasTest : public PageTestBase,
+ public ::testing::WithParamInterface<TestParams> {
protected:
OffscreenCanvasTest();
void SetUp() override;
void TearDown() override;
- HTMLCanvasElement& CanvasElement() const { return *canvas_element_; }
- OffscreenCanvas& OSCanvas() const { return *offscreen_canvas_; }
+ OffscreenCanvas& offscreen_canvas() const { return *offscreen_canvas_; }
CanvasResourceDispatcher* Dispatcher() const {
return offscreen_canvas_->GetOrCreateResourceDispatcher();
}
- OffscreenCanvasRenderingContext2D& Context() const { return *context_; }
ScriptState* GetScriptState() const {
return ToScriptStateForMainWorld(GetDocument().GetFrame());
}
- ScopedTestingPlatformSupport<TestingPlatformSupport>& platform() {
- return platform_;
- }
private:
- Persistent<HTMLCanvasElement> canvas_element_;
Persistent<OffscreenCanvas> offscreen_canvas_;
Persistent<OffscreenCanvasRenderingContext2D> context_;
- ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
FakeGLES2Interface gl_;
};
@@ -62,11 +71,20 @@ void OffscreenCanvasTest::SetUp() {
WTF::BindRepeating(factory, WTF::Unretained(&gl_)));
PageTestBase::SetUp();
SetHtmlInnerHTML("<body><canvas id='c'></canvas></body>");
- canvas_element_ = ToHTMLCanvasElement(GetElementById("c"));
+ HTMLCanvasElement* canvas_element = ToHTMLCanvasElement(GetElementById("c"));
+
DummyExceptionStateForTesting exception_state;
offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen(
- *canvas_element_, exception_state);
+ *canvas_element, exception_state);
+ // |offscreen_canvas_| should inherit the FrameSinkId from |canvas_element|s
+ // SurfaceLayerBridge, but in tests this id is zero; fill it up by hand.
+ offscreen_canvas_->SetFrameSinkId(kClientId, kSinkId);
+
CanvasContextCreationAttributesCore attrs;
+ if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) {
+ attrs.alpha = GetParam().alpha;
+ attrs.low_latency = GetParam().low_latency;
+ }
context_ = static_cast<OffscreenCanvasRenderingContext2D*>(
offscreen_canvas_->GetCanvasRenderingContext(&GetDocument(), String("2d"),
attrs));
@@ -81,4 +99,84 @@ TEST_F(OffscreenCanvasTest, AnimationNotInitiallySuspended) {
EXPECT_FALSE(Dispatcher()->IsAnimationSuspended());
}
+// Verifies that an offscreen_canvas()s PushFrame()/Commit() has the appropriate
+// opacity/blending information sent to the CompositorFrameSink.
+TEST_P(OffscreenCanvasTest, CompositorFrameOpacity) {
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform;
+ ScriptState::Scope scope(GetScriptState());
+ ::testing::InSequence s;
+
+ // To intercept SubmitCompositorFrame/SubmitCompositorFrameSync messages sent
+ // by OffscreenCanvas's CanvasResourceDispatcher, we have to override the Mojo
+ // EmbeddedFrameSinkProvider interface impl and its CompositorFrameSinkClient.
+ MockEmbeddedFrameSinkProvider mock_embedded_frame_sink_provider;
+ mojo::Binding<mojom::blink::EmbeddedFrameSinkProvider>
+ embedded_frame_sink_provider_binding(&mock_embedded_frame_sink_provider);
+ auto override =
+ mock_embedded_frame_sink_provider.CreateScopedOverrideMojoInterface(
+ &embedded_frame_sink_provider_binding);
+
+ // Call here DidDraw() to simulate having drawn something before PushFrame()/
+ // Commit(); DidDraw() will in turn cause a CanvasResourceDispatcher to be
+ // created and a CreateCompositorFrameSink() to be issued; this sink will get
+ // a SetNeedsBeginFrame() message sent upon construction.
+ mock_embedded_frame_sink_provider
+ .set_num_expected_set_needs_begin_frame_on_sink_construction(1);
+ EXPECT_CALL(mock_embedded_frame_sink_provider,
+ CreateCompositorFrameSink_(viz::FrameSinkId(kClientId, kSinkId)));
+ offscreen_canvas().DidDraw();
+ platform->RunUntilIdle();
+
+ const bool context_alpha = GetParam().alpha;
+
+ const auto canvas_resource = CanvasResourceSharedBitmap::Create(
+ offscreen_canvas().Size(), CanvasColorParams(), nullptr /* provider */,
+ kLow_SkFilterQuality);
+ EXPECT_TRUE(!!canvas_resource);
+
+ EXPECT_CALL(mock_embedded_frame_sink_provider.mock_compositor_frame_sink(),
+ SubmitCompositorFrame_(_))
+ .WillOnce(::testing::WithArg<0>(
+ ::testing::Invoke([context_alpha](const viz::CompositorFrame* frame) {
+ ASSERT_EQ(frame->render_pass_list.size(), 1u);
+
+ const auto& quad_list = frame->render_pass_list[0]->quad_list;
+ ASSERT_EQ(quad_list.size(), 1u);
+ EXPECT_EQ(quad_list.front()->needs_blending, context_alpha);
+
+ const auto& shared_quad_state_list =
+ frame->render_pass_list[0]->shared_quad_state_list;
+ ASSERT_EQ(shared_quad_state_list.size(), 1u);
+ EXPECT_NE(shared_quad_state_list.front()->are_contents_opaque,
+ context_alpha);
+ })));
+ offscreen_canvas().PushFrame(canvas_resource, SkIRect::MakeWH(10, 10));
+ platform->RunUntilIdle();
+
+ EXPECT_CALL(mock_embedded_frame_sink_provider.mock_compositor_frame_sink(),
+ SubmitCompositorFrameSync_(_))
+ .WillOnce(::testing::WithArg<0>(
+ ::testing::Invoke([context_alpha](const viz::CompositorFrame* frame) {
+ ASSERT_EQ(frame->render_pass_list.size(), 1u);
+
+ const auto& quad_list = frame->render_pass_list[0]->quad_list;
+ ASSERT_EQ(quad_list.size(), 1u);
+ EXPECT_EQ(quad_list.front()->needs_blending, context_alpha);
+
+ const auto& shared_quad_state_list =
+ frame->render_pass_list[0]->shared_quad_state_list;
+ ASSERT_EQ(shared_quad_state_list.size(), 1u);
+ EXPECT_NE(shared_quad_state_list.front()->are_contents_opaque,
+ context_alpha);
+ })));
+ offscreen_canvas().Commit(canvas_resource, SkIRect::MakeWH(10, 10));
+ platform->RunUntilIdle();
+}
+
+const TestParams kTestCases[] = {{false /* alpha */, false /* low_latency */},
+ {false, true},
+ {true, false},
+ {true, true}};
+
+INSTANTIATE_TEST_CASE_P(, OffscreenCanvasTest, ValuesIn(kTestCases));
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
index 291c37fc2e1..37e47045d2b 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -33,8 +33,8 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(
const CanvasContextCreationAttributesCore& attrs)
: CanvasRenderingContext(canvas, attrs) {
ExecutionContext* execution_context = canvas->GetTopExecutionContext();
- if (execution_context->IsDocument()) {
- Settings* settings = ToDocument(execution_context)->GetSettings();
+ if (auto* document = DynamicTo<Document>(execution_context)) {
+ Settings* settings = document->GetSettings();
if (settings->GetDisableReadingFromCanvas())
canvas->SetDisableReadingFromCanvasTrue();
return;
@@ -418,7 +418,7 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal(
false);
text_run.SetNormalizeSpace(true);
// Draw the item text at the correct point.
- FloatPoint location(x, y + GetFontBaseline(font_metrics));
+ FloatPoint location(x, y + GetFontBaseline(*font_data));
double font_width = font.Width(text_run);
bool use_max_width = (max_width && *max_width < font_width);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
index aed21d6d0f6..b9a3f6e7f1b 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -39,7 +39,7 @@
attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
[RaisesException] CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
- [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=NullString] DOMString repetitionType);
+ [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetitionType);
// shadows
attribute unrestricted double shadowOffsetX;
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index d681b440b04..27c7198ff1f 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -95,8 +95,7 @@ PermissionService* ClipboardPromise::GetPermissionService() {
}
bool ClipboardPromise::IsFocusedDocument(ExecutionContext* context) {
- DCHECK(context->IsDocument());
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = To<Document>(context);
return doc && doc->hasFocus();
}
@@ -182,8 +181,8 @@ void ClipboardPromise::HandleReadTextWithPermission(PermissionStatus status) {
// TODO(garykac): This currently only handles plain text.
void ClipboardPromise::HandleWrite(DataTransfer* data) {
// Scan DataTransfer and extract data types that we support.
- size_t num_items = data->items()->length();
- for (unsigned long i = 0; i < num_items; i++) {
+ uint32_t num_items = data->items()->length();
+ for (uint32_t i = 0; i < num_items; i++) {
DataTransferItem* item = data->items()->item(i);
DataObjectItem* objectItem = item->GetDataObjectItem();
if (objectItem->Kind() == DataObjectItem::kStringKind &&
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
index 9dc633c5e85..d3a45bab3ea 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -195,10 +195,8 @@ void ToCookieChangeSubscription(
const KURL& DefaultCookieURL(ExecutionContext* execution_context) {
DCHECK(execution_context);
- if (execution_context->IsDocument()) {
- Document* document = ToDocument(execution_context);
+ if (auto* document = DynamicTo<Document>(execution_context))
return document->CookieURL();
- }
DCHECK(execution_context->IsServiceWorkerGlobalScope());
ServiceWorkerGlobalScope* scope =
@@ -209,10 +207,8 @@ const KURL& DefaultCookieURL(ExecutionContext* execution_context) {
KURL DefaultSiteForCookies(ExecutionContext* execution_context) {
DCHECK(execution_context);
- if (execution_context->IsDocument()) {
- Document* document = ToDocument(execution_context);
+ if (auto* document = DynamicTo<Document>(execution_context))
return document->SiteForCookies();
- }
DCHECK(execution_context->IsServiceWorkerGlobalScope());
ServiceWorkerGlobalScope* scope =
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
index 39b513ca069..e7b9e67b932 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc
@@ -4,23 +4,37 @@
#include "third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h"
+#include "third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h"
+
namespace blink {
AuthenticatorAttestationResponse* AuthenticatorAttestationResponse::Create(
DOMArrayBuffer* client_data_json,
- DOMArrayBuffer* attestation_object) {
- return new AuthenticatorAttestationResponse(client_data_json,
- attestation_object);
+ DOMArrayBuffer* attestation_object,
+ Vector<mojom::AuthenticatorTransport> transports) {
+ return new AuthenticatorAttestationResponse(
+ client_data_json, attestation_object, std::move(transports));
}
AuthenticatorAttestationResponse::AuthenticatorAttestationResponse(
DOMArrayBuffer* client_data_json,
- DOMArrayBuffer* attestation_object)
+ DOMArrayBuffer* attestation_object,
+ Vector<mojom::AuthenticatorTransport> transports)
: AuthenticatorResponse(client_data_json),
- attestation_object_(attestation_object) {}
+ attestation_object_(attestation_object),
+ transports_(std::move(transports)) {}
AuthenticatorAttestationResponse::~AuthenticatorAttestationResponse() = default;
+Vector<String> AuthenticatorAttestationResponse::getTransports() const {
+ Vector<String> ret;
+ for (auto transport : transports_) {
+ ret.emplace_back(mojo::ConvertTo<String>(transport));
+ }
+ std::sort(ret.begin(), ret.end(), WTF::CodePointCompareLessThan);
+ return ret;
+}
+
void AuthenticatorAttestationResponse::Trace(blink::Visitor* visitor) {
visitor->Trace(attestation_object_);
AuthenticatorResponse::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
index 5ca9d3f2741..c0ffb0cb22d 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
@@ -5,10 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_
+#include "third_party/blink/public/platform/modules/webauthn/authenticator.mojom-blink.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/credentialmanager/authenticator_response.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -19,7 +22,8 @@ class MODULES_EXPORT AuthenticatorAttestationResponse final
public:
static AuthenticatorAttestationResponse* Create(
DOMArrayBuffer* client_data_json,
- DOMArrayBuffer* attestation_object);
+ DOMArrayBuffer* attestation_object,
+ Vector<mojom::AuthenticatorTransport> transports);
~AuthenticatorAttestationResponse() override;
@@ -27,13 +31,18 @@ class MODULES_EXPORT AuthenticatorAttestationResponse final
return attestation_object_.Get();
}
+ Vector<String> getTransports() const;
+
void Trace(blink::Visitor*) override;
private:
- explicit AuthenticatorAttestationResponse(DOMArrayBuffer* client_data_json,
- DOMArrayBuffer* attestation_object);
+ AuthenticatorAttestationResponse(
+ DOMArrayBuffer* client_data_json,
+ DOMArrayBuffer* attestation_object,
+ Vector<mojom::AuthenticatorTransport> transports);
const Member<DOMArrayBuffer> attestation_object_;
+ const Vector<mojom::AuthenticatorTransport> transports_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
index 4205aeddb31..980b705aaca 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl
@@ -10,4 +10,5 @@
Exposed=Window
] interface AuthenticatorAttestationResponse : AuthenticatorResponse {
[SameObject] readonly attribute ArrayBuffer attestationObject;
+ [RuntimeEnabled=WebAuthGetTransports] sequence<AuthenticatorTransport> getTransports();
};
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
index 9d34774512e..aa6950e46b3 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc
@@ -12,8 +12,8 @@
namespace blink {
-CredentialManagerProxy::CredentialManagerProxy(Document* document) {
- LocalFrame* frame = document->GetFrame();
+CredentialManagerProxy::CredentialManagerProxy(Document& document) {
+ LocalFrame* frame = document.GetFrame();
DCHECK(frame);
frame->GetInterfaceProvider().GetInterface(&credential_manager_);
frame->GetInterfaceProvider().GetInterface(
@@ -23,13 +23,12 @@ CredentialManagerProxy::CredentialManagerProxy(Document* document) {
CredentialManagerProxy::~CredentialManagerProxy() {}
// static
-CredentialManagerProxy* CredentialManagerProxy::From(Document* document) {
- DCHECK(document);
+CredentialManagerProxy* CredentialManagerProxy::From(Document& document) {
auto* supplement =
Supplement<Document>::From<CredentialManagerProxy>(document);
if (!supplement) {
supplement = new CredentialManagerProxy(document);
- ProvideTo(*document, supplement);
+ ProvideTo(document, supplement);
}
return supplement;
}
@@ -38,7 +37,7 @@ CredentialManagerProxy* CredentialManagerProxy::From(Document* document) {
CredentialManagerProxy* CredentialManagerProxy::From(
ScriptState* script_state) {
DCHECK(script_state->ContextIsValid());
- return From(ToDocumentOrNull(ExecutionContext::From(script_state)));
+ return From(To<Document>(*ExecutionContext::From(script_state)));
}
// static
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
index 5d9c7b68b00..ff96bb62a3d 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h
@@ -35,7 +35,7 @@ class MODULES_EXPORT CredentialManagerProxy
public:
static const char kSupplementName[];
- explicit CredentialManagerProxy(Document*);
+ explicit CredentialManagerProxy(Document&);
virtual ~CredentialManagerProxy();
mojom::blink::CredentialManager* CredentialManager() {
@@ -51,7 +51,7 @@ class MODULES_EXPORT CredentialManagerProxy
// Both flavors must be called only with arguments representing a valid
// context corresponding to an attached Document.
static CredentialManagerProxy* From(ScriptState*);
- static CredentialManagerProxy* From(Document*);
+ static CredentialManagerProxy* From(Document&);
private:
mojom::blink::AuthenticatorPtr authenticator_;
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
index 54615eef0ef..2f3eb1f6f5a 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -130,6 +130,9 @@ TypeConverter<CredentialManagerError, AuthenticatorStatus>::Convert(
return CredentialManagerError::NOT_IMPLEMENTED;
case blink::mojom::blink::AuthenticatorStatus::NOT_FOCUSED:
return CredentialManagerError::NOT_FOCUSED;
+ case blink::mojom::blink::AuthenticatorStatus::
+ RESIDENT_CREDENTIALS_UNSUPPORTED:
+ return CredentialManagerError::RESIDENT_CREDENTIALS_UNSUPPORTED;
case blink::mojom::blink::AuthenticatorStatus::ALGORITHM_UNSUPPORTED:
return CredentialManagerError::ANDROID_ALGORITHM_UNSUPPORTED;
case blink::mojom::blink::AuthenticatorStatus::EMPTY_ALLOW_CREDENTIALS:
@@ -211,6 +214,23 @@ AuthenticatorTransport TypeConverter<AuthenticatorTransport, String>::Convert(
}
// static
+String TypeConverter<String, AuthenticatorTransport>::Convert(
+ const AuthenticatorTransport& transport) {
+ if (transport == AuthenticatorTransport::USB)
+ return "usb";
+ if (transport == AuthenticatorTransport::NFC)
+ return "nfc";
+ if (transport == AuthenticatorTransport::BLE)
+ return "ble";
+ if (transport == AuthenticatorTransport::CABLE)
+ return "cable";
+ if (transport == AuthenticatorTransport::INTERNAL)
+ return "internal";
+ NOTREACHED();
+ return "usb";
+}
+
+// static
UserVerificationRequirement
TypeConverter<UserVerificationRequirement, String>::Convert(
const String& requirement) {
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
index 987e102a7ad..7da3e65c514 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
@@ -66,6 +66,11 @@ struct TypeConverter<blink::mojom::blink::AuthenticatorTransport, String> {
};
template <>
+struct TypeConverter<String, blink::mojom::blink::AuthenticatorTransport> {
+ static String Convert(const blink::mojom::blink::AuthenticatorTransport&);
+};
+
+template <>
struct TypeConverter<blink::mojom::blink::UserVerificationRequirement, String> {
static blink::mojom::blink::UserVerificationRequirement Convert(
const String&);
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
index 863f1fd71b0..4daa0598c63 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -241,6 +241,11 @@ DOMException* CredentialManagerErrorToDOMException(
return DOMException::Create(DOMExceptionCode::kNotAllowedError,
"The operation is not allowed at this time "
"because the page does not have focus.");
+ case CredentialManagerError::RESIDENT_CREDENTIALS_UNSUPPORTED:
+ return DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ "Resident credentials or empty "
+ "'allowCredentials' lists are not supported "
+ "at this time.");
case CredentialManagerError::ANDROID_ALGORITHM_UNSUPPORTED:
return DOMException::Create(DOMExceptionCode::kNotSupportedError,
"None of the algorithms specified in "
@@ -335,8 +340,8 @@ void OnMakePublicKeyCredentialComplete(
DOMArrayBuffer* attestation_buffer =
VectorToDOMArrayBuffer(std::move(credential->attestation_object));
AuthenticatorAttestationResponse* authenticator_response =
- AuthenticatorAttestationResponse::Create(client_data_buffer,
- attestation_buffer);
+ AuthenticatorAttestationResponse::Create(
+ client_data_buffer, attestation_buffer, credential->transports);
resolver->Resolve(PublicKeyCredential::Create(credential->info->id, raw_id,
authenticator_response,
{} /* extensions_outputs */));
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
index 2e8d07119b7..2f86f686c2f 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
@@ -148,7 +148,7 @@ TEST(CredentialsContainerTest,
MockCredentialManager mock_credential_manager;
CredentialManagerTestingContext context(&mock_credential_manager);
- auto* proxy = CredentialManagerProxy::From(context.GetDocument());
+ auto* proxy = CredentialManagerProxy::From(*context.GetDocument());
auto promise = CredentialsContainer::Create()->get(
context.GetScriptState(), CredentialRequestOptions());
mock_credential_manager.WaitForCallToGet();
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc
index 6a37e560b13..8d2319a5a68 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/to_v8.h"
#include "third_party/blink/renderer/platform/crypto_result.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
@@ -122,7 +123,8 @@ class DictionaryBuilder : public WebCryptoKeyAlgorithmDictionary {
void SetUint8Array(const char* property_name,
const WebVector<unsigned char>& vector) override {
builder_.Add(property_name,
- DOMUint8Array::Create(vector.Data(), vector.size()));
+ DOMUint8Array::Create(vector.Data(),
+ SafeCast<wtf_size_t>(vector.size())));
}
private:
@@ -227,7 +229,7 @@ bool CryptoKey::ParseUsageMask(const Vector<String>& usages,
WebCryptoKeyUsageMask& mask,
CryptoResult* result) {
mask = 0;
- for (size_t i = 0; i < usages.size(); ++i) {
+ for (wtf_size_t i = 0; i < usages.size(); ++i) {
WebCryptoKeyUsageMask usage = KeyUsageStringToMask(usages[i]);
if (!usage) {
result->CompleteWithError(kWebCryptoErrorTypeType,
diff --git a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
index 013cfada404..ab0355a47e7 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
@@ -228,17 +228,18 @@ class ErrorContext {
return String();
StringBuilder result;
- const char* separator = ": ";
+ constexpr const char* separator = ": ";
- size_t length = (messages_.size() - 1) * strlen(separator);
- for (size_t i = 0; i < messages_.size(); ++i)
+ wtf_size_t length = (messages_.size() - 1) * strlen(separator);
+ for (wtf_size_t i = 0; i < messages_.size(); ++i)
length += strlen(messages_[i]);
result.ReserveCapacity(length);
- for (size_t i = 0; i < messages_.size(); ++i) {
+ for (wtf_size_t i = 0; i < messages_.size(); ++i) {
if (i)
result.Append(separator, strlen(separator));
- result.Append(messages_[i], strlen(messages_[i]));
+ result.Append(messages_[i],
+ static_cast<wtf_size_t>(strlen(messages_[i])));
}
return result.ToString();
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
index 4ab1a291ccd..ffd88e09052 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
@@ -80,7 +80,7 @@ scoped_refptr<Image> CSSPaintDefinition::Paint(
MaybeCreatePaintInstance();
v8::Isolate* isolate = script_state_->GetIsolate();
- v8::Local<v8::Object> instance = instance_.NewLocal(isolate);
+ v8::Local<v8::Value> instance = instance_.NewLocal(isolate);
// We may have failed to create an instance class, in which case produce an
// invalid image.
@@ -144,11 +144,11 @@ void CSSPaintDefinition::MaybeCreatePaintInstance() {
v8::Local<v8::Function> constructor = constructor_.NewLocal(isolate);
DCHECK(!IsUndefinedOrNull(constructor));
- v8::Local<v8::Object> paint_instance;
- if (V8ObjectConstructor::NewInstance(isolate, constructor)
- .ToLocal(&paint_instance)) {
+ v8::Local<v8::Value> paint_instance;
+ if (V8ScriptRunner::CallAsConstructor(
+ isolate, constructor, ExecutionContext::From(script_state_), 0, {})
+ .ToLocal(&paint_instance))
instance_.Set(isolate, paint_instance);
- }
did_call_constructor_ = true;
}
@@ -156,7 +156,7 @@ void CSSPaintDefinition::MaybeCreatePaintInstance() {
void CSSPaintDefinition::Trace(Visitor* visitor) {
visitor->Trace(constructor_.Cast<v8::Value>());
visitor->Trace(paint_.Cast<v8::Value>());
- visitor->Trace(instance_.Cast<v8::Value>());
+ visitor->Trace(instance_);
visitor->Trace(script_state_);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
index dede4c7bf87..4622a7b84a1 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
@@ -97,7 +97,7 @@ class MODULES_EXPORT CSSPaintDefinition final
TraceWrapperV8Reference<v8::Function> paint_;
// At the moment there is only ever one instance of a paint class per type.
- TraceWrapperV8Reference<v8::Object> instance_;
+ TraceWrapperV8Reference<v8::Value> instance_;
bool did_call_constructor_;
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
index 7d69e7685fb..e7f43a5a2d2 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
@@ -36,7 +36,7 @@
attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
[RaisesException] CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
- [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=NullString] DOMString repetitionType);
+ [CallWith=ScriptState, RaisesException] CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetitionType);
// shadows
attribute unrestricted double shadowOffsetX;
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
index 0095e149001..b668a6f2623 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -124,7 +124,7 @@ bool PaintWorklet::NeedsToCreateGlobalScope() {
WorkletGlobalScopeProxy* PaintWorklet::CreateGlobalScope() {
DCHECK(NeedsToCreateGlobalScope());
return new PaintWorkletGlobalScopeProxy(
- ToDocument(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
+ To<Document>(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
pending_generator_registry_, GetNumberOfGlobalScopes() + 1);
}
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
index 69116afaa98..7e2bbcf3193 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -111,9 +111,7 @@ PaintWorkletGlobalScope::PaintWorkletGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
WorkerReportingProxy& reporting_proxy,
PaintWorkletPendingGeneratorRegistry* pending_generator_registry)
- : MainThreadWorkletGlobalScope(frame,
- std::move(creation_params),
- reporting_proxy),
+ : WorkletGlobalScope(std::move(creation_params), reporting_proxy, frame),
pending_generator_registry_(pending_generator_registry) {}
PaintWorkletGlobalScope::~PaintWorkletGlobalScope() = default;
@@ -121,9 +119,8 @@ PaintWorkletGlobalScope::~PaintWorkletGlobalScope() = default;
void PaintWorkletGlobalScope::Dispose() {
MainThreadDebugger::Instance()->ContextWillBeDestroyed(
ScriptController()->GetScriptState());
-
pending_generator_registry_ = nullptr;
- MainThreadWorkletGlobalScope::Dispose();
+ WorkletGlobalScope::Dispose();
}
void PaintWorkletGlobalScope::registerPaint(
@@ -230,7 +227,7 @@ double PaintWorkletGlobalScope::devicePixelRatio() const {
void PaintWorkletGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(paint_definitions_);
visitor->Trace(pending_generator_registry_);
- MainThreadWorkletGlobalScope::Trace(visitor);
+ WorkletGlobalScope::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
index 1817e5dfc8b..6bd200d8dde 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/workers/main_thread_worklet_global_scope.h"
+#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -18,8 +18,7 @@ class CSSPaintDefinition;
class ExceptionState;
class WorkerReportingProxy;
-class MODULES_EXPORT PaintWorkletGlobalScope final
- : public MainThreadWorkletGlobalScope {
+class MODULES_EXPORT PaintWorkletGlobalScope final : public WorkletGlobalScope {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PaintWorkletGlobalScope);
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
index c3da5aac23f..d4c9ec466ab 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
@@ -73,7 +73,7 @@ void PaintWorkletGlobalScopeProxy::WorkletObjectDestroyed() {
void PaintWorkletGlobalScopeProxy::TerminateWorkletGlobalScope() {
DCHECK(IsMainThread());
- global_scope_->Terminate();
+ global_scope_->Dispose();
// Nullify these fields to cut a potential reference cycle.
global_scope_ = nullptr;
reporting_proxy_.reset();
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
index a9f8c45c0bc..a58249d1bd6 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
@@ -106,7 +106,8 @@ class PaintWorkletTest : public PageTestBase {
TEST_F(PaintWorkletTest, GarbageCollectionOfCSSPaintDefinition) {
PaintWorkletGlobalScope* global_scope = GetProxy()->global_scope();
global_scope->ScriptController()->Evaluate(
- ScriptSourceCode("registerPaint('foo', class { paint() { } });"));
+ ScriptSourceCode("registerPaint('foo', class { paint() { } });"),
+ kSharableCrossOrigin);
CSSPaintDefinition* definition = global_scope->FindDefinition("foo");
DCHECK(definition);
@@ -147,7 +148,8 @@ TEST_F(PaintWorkletTest, GarbageCollectionOfCSSPaintDefinition) {
TEST_F(PaintWorkletTest, PaintWithNullPaintArguments) {
PaintWorkletGlobalScope* global_scope = GetProxy()->global_scope();
global_scope->ScriptController()->Evaluate(
- ScriptSourceCode("registerPaint('foo', class { paint() { } });"));
+ ScriptSourceCode("registerPaint('foo', class { paint() { } });"),
+ kSharableCrossOrigin);
CSSPaintDefinition* definition = global_scope->FindDefinition("foo");
ASSERT_TRUE(definition);
@@ -168,7 +170,8 @@ TEST_F(PaintWorkletTest, PaintWithNullPaintArguments) {
TEST_F(PaintWorkletTest, SinglyRegisteredDocumentDefinitionNotUsed) {
PaintWorkletGlobalScope* global_scope = GetProxy()->global_scope();
global_scope->ScriptController()->Evaluate(
- ScriptSourceCode("registerPaint('foo', class { paint() { } });"));
+ ScriptSourceCode("registerPaint('foo', class { paint() { } });"),
+ kSharableCrossOrigin);
CSSPaintImageGeneratorImpl* generator =
static_cast<CSSPaintImageGeneratorImpl*>(
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
index 01c1ade0c72..4e4431be7aa 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
@@ -92,12 +92,12 @@ void DeviceMotionController::RegisterWithDispatcher() {
frame->GetTaskRunner(TaskType::kSensor);
motion_event_pump_ = new DeviceMotionEventPump(task_runner);
}
- motion_event_pump_->AddController(this);
+ motion_event_pump_->SetController(this);
}
void DeviceMotionController::UnregisterWithDispatcher() {
if (motion_event_pump_)
- motion_event_pump_->RemoveController(this);
+ motion_event_pump_->RemoveController();
}
Event* DeviceMotionController::LastEvent() const {
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
index 0ef859cca95..47deaede78a 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
@@ -4,9 +4,12 @@
#include <cmath>
+#include "base/auto_reset.h"
#include "services/device/public/mojom/sensor.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h"
#include "ui/gfx/geometry/angle_conversions.h"
@@ -33,13 +36,28 @@ DeviceMotionEventPump::~DeviceMotionEventPump() {
StopIfObserving();
}
+void DeviceMotionEventPump::SetController(PlatformEventController* controller) {
+ DCHECK(controller);
+ DCHECK(!controller_);
+
+ controller_ = controller;
+ StartListening(controller_->GetDocument()
+ ? controller_->GetDocument()->GetFrame()
+ : nullptr);
+}
+
+void DeviceMotionEventPump::RemoveController() {
+ controller_ = nullptr;
+ StopListening();
+}
+
DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() {
return data_.Get();
}
void DeviceMotionEventPump::Trace(blink::Visitor* visitor) {
visitor->Trace(data_);
- PlatformEventDispatcher::Trace(visitor);
+ visitor->Trace(controller_);
}
void DeviceMotionEventPump::StartListening(LocalFrame* frame) {
@@ -81,13 +99,18 @@ void DeviceMotionEventPump::SendStopMessage() {
gyroscope_.Stop();
}
+void DeviceMotionEventPump::NotifyController() {
+ DCHECK(controller_);
+ controller_->DidUpdateData();
+}
+
void DeviceMotionEventPump::FireEvent(TimerBase*) {
DeviceMotionData* data = GetDataFromSharedMemory();
// data is null if not all sensors are active
if (data) {
data_ = data;
- NotifyControllers();
+ NotifyController();
}
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
index 751d5660bc3..b9f30170d1e 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_EVENT_PUMP_H_
#include "base/macros.h"
-#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h"
#include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -14,21 +13,22 @@
namespace blink {
class DeviceMotionData;
+class PlatformEventController;
class MODULES_EXPORT DeviceMotionEventPump
: public GarbageCollectedFinalized<DeviceMotionEventPump>,
- public DeviceSensorEventPump,
- public PlatformEventDispatcher {
- USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump);
-
+ public DeviceSensorEventPump {
public:
explicit DeviceMotionEventPump(scoped_refptr<base::SingleThreadTaskRunner>);
~DeviceMotionEventPump() override;
+ void SetController(PlatformEventController*);
+ void RemoveController();
+
// Note that the returned object is owned by this class.
DeviceMotionData* LatestDeviceMotionData();
- void Trace(blink::Visitor*) override;
+ void Trace(blink::Visitor*);
// DeviceSensorEventPump:
void SendStartMessage(LocalFrame* frame) override;
@@ -45,9 +45,9 @@ class MODULES_EXPORT DeviceMotionEventPump
private:
friend class DeviceMotionEventPumpTest;
- // Inherited from PlatformEventDispatcher.
- void StartListening(LocalFrame*) override;
- void StopListening() override;
+ void StartListening(LocalFrame*);
+ void StopListening();
+ void NotifyController();
// DeviceSensorEventPump:
bool SensorsReadyOrErrored() const override;
@@ -55,6 +55,7 @@ class MODULES_EXPORT DeviceMotionEventPump
DeviceMotionData* GetDataFromSharedMemory();
Member<DeviceMotionData> data_;
+ WeakMember<PlatformEventController> controller_;
DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump);
};
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
index a9d5238ec33..3001690cdc5 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
@@ -46,13 +46,11 @@ class MockDeviceMotionController final
int number_of_events() const { return number_of_events_; }
- void RegisterWithDispatcher() override { motion_pump_->AddController(this); }
+ void RegisterWithDispatcher() override { motion_pump_->SetController(this); }
bool HasLastData() override { return motion_pump_->LatestDeviceMotionData(); }
- void UnregisterWithDispatcher() override {
- motion_pump_->RemoveController(this);
- }
+ void UnregisterWithDispatcher() override { motion_pump_->RemoveController(); }
const DeviceMotionData* data() {
return motion_pump_->LatestDeviceMotionData();
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
index 6df6db6ba2e..8e132701f9a 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -15,7 +16,6 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
index 362f5c3f7d1..145c861b579 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace {
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
index 5e777aab9b4..217e50af7f3 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
@@ -20,7 +20,8 @@ DeviceOrientationInspectorAgent::~DeviceOrientationInspectorAgent() = default;
DeviceOrientationInspectorAgent::DeviceOrientationInspectorAgent(
InspectedFrames* inspected_frames)
: inspected_frames_(inspected_frames),
- sensor_agent_(new SensorInspectorAgent(inspected_frames->Root())),
+ sensor_agent_(
+ new SensorInspectorAgent(inspected_frames->Root()->GetDocument())),
enabled_(&agent_state_, /*default_value=*/false),
alpha_(&agent_state_, /*default_value=*/0.0),
beta_(&agent_state_, /*default_value=*/0.0),
@@ -79,6 +80,7 @@ void DeviceOrientationInspectorAgent::DidCommitLoadForLocalFrame(
if (frame == inspected_frames_->Root()) {
// New document in main frame - apply override there.
// No need to cleanup previous one, as it's already gone.
+ sensor_agent_->DidCommitLoadForLocalFrame(frame);
Restore();
}
}
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc b/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc
index 2f8f53f7a33..0c91daa2cbb 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc
@@ -47,9 +47,9 @@ constexpr int kMaxDepth = 4;
// App Indexing supports strings up to length 20k.
constexpr int kMaxStringLength = 200;
// Enforced by App Indexing, so stop processing early if possible.
-constexpr size_t kMaxNumFields = 20;
+constexpr wtf_size_t kMaxNumFields = 20;
// Enforced by App Indexing, so stop processing early if possible.
-constexpr size_t kMaxRepeatedSize = 100;
+constexpr wtf_size_t kMaxRepeatedSize = 100;
constexpr char kJSONLDKeyType[] = "@type";
constexpr char kJSONLDKeyGraph[] = "@graph";
@@ -101,7 +101,7 @@ bool parseRepeatedValue(const JSONArray& arr,
default:
break;
}
- for (size_t j = 0; j < std::min(arr.size(), kMaxRepeatedSize); ++j) {
+ for (wtf_size_t j = 0; j < std::min(arr.size(), kMaxRepeatedSize); ++j) {
const JSONValue* innerVal = arr.at(j);
if (innerVal->GetType() != type) {
// App Indexing doesn't support mixed types. If there are mixed
@@ -157,7 +157,7 @@ void extractEntity(const JSONObject& val, Entity& entity, int recursionLevel) {
type = "Thing";
}
entity.type = type;
- for (size_t i = 0; i < std::min(val.size(), kMaxNumFields); ++i) {
+ for (wtf_size_t i = 0; i < std::min(val.size(), kMaxNumFields); ++i) {
PropertyPtr property = Property::New();
const JSONObject::Entry& entry = val.at(i);
property->name = entry.first;
diff --git a/chromium/third_party/blink/renderer/modules/encoding/BUILD.gn b/chromium/third_party/blink/renderer/modules/encoding/BUILD.gn
index 62605ab9359..c89c50ed8be 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/encoding/BUILD.gn
@@ -10,7 +10,11 @@ blink_modules_sources("encoding") {
"encoding.h",
"text_decoder.cc",
"text_decoder.h",
+ "text_decoder_stream.cc",
+ "text_decoder_stream.h",
"text_encoder.cc",
"text_encoder.h",
+ "text_encoder_stream.cc",
+ "text_encoder_stream.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
new file mode 100644
index 00000000000..2c0fe8dcd47
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc
@@ -0,0 +1,202 @@
+// 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 "third_party/blink/renderer/modules/encoding/text_decoder_stream.h"
+
+#include <memory>
+#include <utility>
+
+#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/core/streams/retain_wrapper_during_construction.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_default_controller.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/encoding/encoding.h"
+#include "third_party/blink/renderer/modules/encoding/text_decoder_options.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
+#include "third_party/blink/renderer/platform/wtf/string_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_codec.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
+
+namespace blink {
+
+class TextDecoderStream::Transformer final : public TransformStreamTransformer {
+ public:
+ explicit Transformer(ScriptState* script_state,
+ WTF::TextEncoding encoding,
+ bool fatal,
+ bool ignore_bom)
+ : decoder_(NewTextCodec(encoding)),
+ script_state_(script_state),
+ fatal_(fatal),
+ ignore_bom_(ignore_bom),
+ encoding_has_bom_removal_(EncodingHasBomRemoval(encoding)) {}
+
+ // Implements the type conversion part of the "decode and enqueue a chunk"
+ // algorithm.
+ void Transform(v8::Local<v8::Value> chunk,
+ TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ ArrayBufferOrArrayBufferView bufferSource;
+ V8ArrayBufferOrArrayBufferView::ToImpl(
+ script_state_->GetIsolate(), chunk, bufferSource,
+ UnionTypeConversionMode::kNotNullable, exception_state);
+ if (exception_state.HadException())
+ return;
+
+ // This implements the "get a copy of the bytes held by the buffer source"
+ // algorithm (https://heycam.github.io/webidl/#dfn-get-buffer-source-copy).
+ if (bufferSource.IsArrayBufferView()) {
+ const auto* view = bufferSource.GetAsArrayBufferView().View();
+ // If IsDetachedBuffer(O), then throw a TypeError.
+ if (view->buffer()->IsNeutered()) {
+ exception_state.ThrowTypeError(
+ ExceptionMessages::FailedToConvertJSValue("BufferSource"));
+ return;
+ }
+ const char* start = static_cast<const char*>(view->BaseAddress());
+ size_t length = view->byteLength();
+ DecodeAndEnqueue(start, length, WTF::FlushBehavior::kDoNotFlush,
+ controller, exception_state);
+ return;
+ }
+ DCHECK(bufferSource.IsArrayBuffer());
+ const auto* array_buffer = bufferSource.GetAsArrayBuffer();
+ // If IsDetachedBuffer(O), then throw a TypeError.
+ if (array_buffer->IsNeutered()) {
+ exception_state.ThrowTypeError(
+ ExceptionMessages::FailedToConvertJSValue("BufferSource"));
+ return;
+ }
+ const char* start = static_cast<const char*>(array_buffer->Data());
+ size_t length = array_buffer->ByteLength();
+ DecodeAndEnqueue(start, length, WTF::FlushBehavior::kDoNotFlush, controller,
+ exception_state);
+ }
+
+ // Implements the "encode and flush" algorithm.
+ void Flush(TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ DecodeAndEnqueue(nullptr, 0u, WTF::FlushBehavior::kDataEOF, controller,
+ exception_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(script_state_);
+ TransformStreamTransformer::Trace(visitor);
+ }
+
+ private:
+ // Implements the second part of "decode and enqueue a chunk" as well as the
+ // "flush and enqueue" algorithm.
+ void DecodeAndEnqueue(const char* start,
+ size_t length,
+ WTF::FlushBehavior flush,
+ TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) {
+ const UChar kBOM = 0xFEFF;
+
+ bool saw_error = false;
+ String outputChunk =
+ decoder_->Decode(start, length, flush, fatal_, saw_error);
+
+ if (fatal_ && saw_error) {
+ exception_state.ThrowTypeError("The encoded data was not valid.");
+ return;
+ }
+
+ if (outputChunk.IsEmpty())
+ return;
+
+ if (!ignore_bom_ && !bom_seen_) {
+ bom_seen_ = true;
+ if (encoding_has_bom_removal_ && outputChunk[0] == kBOM) {
+ outputChunk.Remove(0);
+ if (outputChunk.IsEmpty())
+ return;
+ }
+ }
+
+ controller->Enqueue(ToV8(outputChunk, script_state_), exception_state);
+ }
+
+ static bool EncodingHasBomRemoval(const WTF::TextEncoding& encoding) {
+ String name(encoding.GetName());
+ return name == "UTF-8" || name == "UTF-16LE" || name == "UTF-16BE";
+ }
+
+ std::unique_ptr<WTF::TextCodec> decoder_;
+ // There is no danger of ScriptState leaking across worlds because a
+ // TextDecoderStream can only be accessed from the world that created it.
+ Member<ScriptState> script_state_;
+ const bool fatal_;
+ const bool ignore_bom_;
+ const bool encoding_has_bom_removal_;
+ bool bom_seen_;
+
+ DISALLOW_COPY_AND_ASSIGN(Transformer);
+};
+
+TextDecoderStream* TextDecoderStream::Create(ScriptState* script_state,
+ const String& label,
+ const TextDecoderOptions& options,
+ ExceptionState& exception_state) {
+ WTF::TextEncoding encoding(
+ label.StripWhiteSpace(&Encoding::IsASCIIWhiteSpace));
+ // The replacement encoding is not valid, but the Encoding API also
+ // rejects aliases of the replacement encoding.
+ if (!encoding.IsValid() ||
+ strcasecmp(encoding.GetName(), "replacement") == 0) {
+ exception_state.ThrowRangeError("The encoding label provided ('" + label +
+ "') is invalid.");
+ return nullptr;
+ }
+
+ return new TextDecoderStream(script_state, encoding, options,
+ exception_state);
+}
+
+TextDecoderStream::~TextDecoderStream() = default;
+
+String TextDecoderStream::encoding() const {
+ return String(encoding_.GetName()).LowerASCII();
+}
+
+ScriptValue TextDecoderStream::readable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return transform_->Readable(script_state, exception_state);
+}
+
+ScriptValue TextDecoderStream::writable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return transform_->Writable(script_state, exception_state);
+}
+
+void TextDecoderStream::Trace(Visitor* visitor) {
+ visitor->Trace(transform_);
+ ScriptWrappable::Trace(visitor);
+}
+
+TextDecoderStream::TextDecoderStream(ScriptState* script_state,
+ const WTF::TextEncoding& encoding,
+ const TextDecoderOptions& options,
+ ExceptionState& exception_state)
+ : transform_(new TransformStream()),
+ encoding_(encoding),
+ fatal_(options.fatal()),
+ ignore_bom_(options.ignoreBOM()) {
+ if (!RetainWrapperDuringConstruction(this, script_state)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot queue task to retain wrapper");
+ return;
+ }
+ transform_->Init(new Transformer(script_state, encoding, fatal_, ignore_bom_),
+ script_state, exception_state);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h
new file mode 100644
index 00000000000..5bf4d10fd40
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h
@@ -0,0 +1,64 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_DECODER_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_DECODER_STREAM_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/streams/transform_stream.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ExceptionState;
+class ScriptState;
+class TextDecoderOptions;
+class Visitor;
+
+// Implements the TextDecoderStream interface as specified at
+// https://encoding.spec.whatwg.org/#interface-textdecoderstream.
+// Converts a stream of binary data in the form of BufferSource chunks to a
+// stream of text data in the form of string chunks. After construction
+// functionality is delegated to the owner TransformStream.
+class TextDecoderStream final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static TextDecoderStream* Create(ScriptState*,
+ const String& label,
+ const TextDecoderOptions&,
+ ExceptionState&);
+ ~TextDecoderStream() override;
+
+ // From text_decoder_stream.idl
+ String encoding() const;
+ bool fatal() const { return fatal_; }
+ bool ignoreBOM() const { return ignore_bom_; }
+ ScriptValue readable(ScriptState*, ExceptionState&) const;
+ ScriptValue writable(ScriptState*, ExceptionState&) const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ class Transformer;
+
+ TextDecoderStream(ScriptState*,
+ const WTF::TextEncoding&,
+ const TextDecoderOptions&,
+ ExceptionState&);
+
+ const TraceWrapperMember<TransformStream> transform_;
+ const WTF::TextEncoding encoding_;
+ const bool fatal_;
+ const bool ignore_bom_;
+
+ DISALLOW_COPY_AND_ASSIGN(TextDecoderStream);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_DECODER_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl
new file mode 100644
index 00000000000..cf5600ceb1e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl
@@ -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.
+
+// https://encoding.spec.whatwg.org/#interface-textdecoderstream
+[
+ Exposed=(Window,Worker),
+ Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options),
+ ConstructorCallWith=ScriptState,
+ RaisesException=Constructor,
+ MeasureAs=TextDecoderStreamConstructor,
+ RuntimeEnabled=EncodingStreams
+] interface TextDecoderStream {
+ readonly attribute DOMString encoding;
+ readonly attribute boolean fatal;
+ readonly attribute boolean ignoreBOM;
+ [CallWith=ScriptState, RaisesException] readonly attribute any readable;
+ [CallWith=ScriptState, RaisesException] readonly attribute any writable;
+};
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
index 81726d58ca0..3f9161f58db 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
@@ -67,10 +67,10 @@ NotShared<DOMUint8Array> TextEncoder::encode(const String& input) {
// are present in the input.
if (input.Is8Bit()) {
result = codec_->Encode(input.Characters8(), input.length(),
- WTF::kEntitiesForUnencodables);
+ WTF::kNoUnencodables);
} else {
result = codec_->Encode(input.Characters16(), input.length(),
- WTF::kEntitiesForUnencodables);
+ WTF::kNoUnencodables);
}
const char* buffer = result.data();
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
new file mode 100644
index 00000000000..1c5aa8fa6e4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
@@ -0,0 +1,200 @@
+// 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 "third_party/blink/renderer/modules/encoding/text_encoder_stream.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/optional.h"
+#include "base/stl_util.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
+#include "third_party/blink/renderer/core/streams/retain_wrapper_during_construction.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_default_controller.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
+#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_codec.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class TextEncoderStream::Transformer final : public TransformStreamTransformer {
+ public:
+ explicit Transformer(ScriptState* script_state)
+ : encoder_(NewTextCodec(WTF::TextEncoding("utf-8"))),
+ script_state_(script_state) {}
+
+ // Implements the "encode and enqueue a chunk" algorithm. For efficiency, only
+ // the characters at the end of chunks are special-cased.
+ void Transform(v8::Local<v8::Value> chunk,
+ TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ // Let |input| be the result of converting |chunk| to a DOMString. If this
+ // throws an exception, then return a promise rejected with that exception.
+ V8StringResource<> input_resource = chunk;
+ if (!input_resource.Prepare(script_state_->GetIsolate(), exception_state))
+ return;
+ const String input = input_resource;
+ if (input.IsEmpty())
+ return;
+
+ const base::Optional<UChar> high_surrogate = pending_high_surrogate_;
+ pending_high_surrogate_ = base::nullopt;
+ CString prefix;
+ CString result;
+ if (input.Is8Bit()) {
+ if (high_surrogate.has_value()) {
+ // An 8-bit code unit can never be part of an astral character, so no
+ // check is needed.
+ prefix = ReplacementCharacterInUtf8();
+ }
+ result = encoder_->Encode(input.Characters8(), input.length(),
+ WTF::kNoUnencodables);
+ } else {
+ bool have_output =
+ Encode16BitString(input, high_surrogate, &prefix, &result);
+ if (!have_output)
+ return;
+ }
+
+ DOMUint8Array* array =
+ CreateDOMUint8ArrayFromTwoCStringsConcatenated(prefix, result);
+ controller->Enqueue(ToV8(array, script_state_), exception_state);
+ }
+
+ // Implements the "encode and flush" algorithm.
+ void Flush(TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ if (!pending_high_surrogate_.has_value())
+ return;
+
+ const CString replacement_character = ReplacementCharacterInUtf8();
+ const uint8_t* u8buffer =
+ reinterpret_cast<const uint8_t*>(replacement_character.data());
+ controller->Enqueue(
+ ToV8(DOMUint8Array::Create(u8buffer, replacement_character.length()),
+ script_state_),
+ exception_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(script_state_);
+ TransformStreamTransformer::Trace(visitor);
+ }
+
+ private:
+ static CString ReplacementCharacterInUtf8() {
+ constexpr char kRawBytes[] = {0xEF, 0xBF, 0xBD};
+ return CString(kRawBytes, sizeof(kRawBytes));
+ }
+
+ static DOMUint8Array* CreateDOMUint8ArrayFromTwoCStringsConcatenated(
+ const CString& string1,
+ const CString& string2) {
+ const size_t length1 = string1.length();
+ const size_t length2 = string2.length();
+ DOMUint8Array* const array = DOMUint8Array::Create(length1 + length2);
+ if (length1 > 0)
+ memcpy(array->Data(), string1.data(), length1);
+ if (length2 > 0)
+ memcpy(array->Data() + length1, string2.data(), length2);
+ return array;
+ }
+
+ // Returns true if either |*prefix| or |*result| have been set to a non-empty
+ // value.
+ bool Encode16BitString(const String& input,
+ base::Optional<UChar> high_surrogate,
+ CString* prefix,
+ CString* result) {
+ const UChar* begin = input.Characters16();
+ const UChar* end = input.Characters16() + input.length();
+ DCHECK_GT(end, begin);
+ if (high_surrogate.has_value()) {
+ if (*begin >= 0xDC00 && *begin <= 0xDFFF) {
+ const UChar astral_character[2] = {high_surrogate.value(), *begin};
+ // Third argument is ignored, as above.
+ *prefix =
+ encoder_->Encode(astral_character, base::size(astral_character),
+ WTF::kNoUnencodables);
+ ++begin;
+ if (begin == end)
+ return true;
+ } else {
+ *prefix = ReplacementCharacterInUtf8();
+ }
+ }
+
+ const UChar final_token = *(end - 1);
+ if (final_token >= 0xD800 && final_token <= 0xDBFF) {
+ pending_high_surrogate_ = final_token;
+ --end;
+ if (begin == end)
+ return prefix->length() != 0;
+ }
+
+ // Third argument is ignored, as above.
+ *result =
+ encoder_->Encode(begin, end - begin, WTF::kEntitiesForUnencodables);
+ DCHECK_NE(result->length(), 0u);
+ return true;
+ }
+
+ std::unique_ptr<WTF::TextCodec> encoder_;
+ // There is no danger of ScriptState leaking across worlds because a
+ // TextEncoderStream can only be accessed from the world that created it.
+ Member<ScriptState> script_state_;
+ base::Optional<UChar> pending_high_surrogate_;
+
+ DISALLOW_COPY_AND_ASSIGN(Transformer);
+};
+
+TextEncoderStream* TextEncoderStream::Create(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ return new TextEncoderStream(script_state, exception_state);
+}
+
+TextEncoderStream::~TextEncoderStream() = default;
+
+String TextEncoderStream::encoding() const {
+ return "utf-8";
+}
+
+ScriptValue TextEncoderStream::readable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return transform_->Readable(script_state, exception_state);
+}
+
+ScriptValue TextEncoderStream::writable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return transform_->Writable(script_state, exception_state);
+}
+
+void TextEncoderStream::Trace(Visitor* visitor) {
+ visitor->Trace(transform_);
+ ScriptWrappable::Trace(visitor);
+}
+
+TextEncoderStream::TextEncoderStream(ScriptState* script_state,
+ ExceptionState& exception_state)
+ : transform_(new TransformStream()) {
+ if (!RetainWrapperDuringConstruction(this, script_state)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot queue task to retain wrapper");
+ return;
+ }
+ transform_->Init(new Transformer(script_state), script_state,
+ exception_state);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h
new file mode 100644
index 00000000000..2aa28ddc7a4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.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 THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_ENCODER_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_ENCODER_STREAM_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/streams/transform_stream.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ExceptionState;
+class ScriptState;
+class Visitor;
+
+// Implements the TextDecoderStream interface as specified at
+// https://encoding.spec.whatwg.org/#interface-textencoderstream.
+// Converts a stream of text data in the form of string chunks to a stream of
+// binary data in the form of UInt8Array chunks. After construction
+// functionality is delegated to the owned TransformStream.
+class TextEncoderStream final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static TextEncoderStream* Create(ScriptState*, ExceptionState&);
+ ~TextEncoderStream() override;
+
+ // From text_encoder_stream.idl
+ String encoding() const;
+ ScriptValue readable(ScriptState*, ExceptionState&) const;
+ ScriptValue writable(ScriptState*, ExceptionState&) const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ class Transformer;
+
+ TextEncoderStream(ScriptState*, ExceptionState&);
+
+ const TraceWrapperMember<TransformStream> transform_;
+
+ DISALLOW_COPY_AND_ASSIGN(TextEncoderStream);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_ENCODER_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl
new file mode 100644
index 00000000000..98ee518e622
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl
@@ -0,0 +1,17 @@
+// 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.
+
+// https://encoding.spec.whatwg.org/#interface-textencoderstream
+[
+ Exposed=(Window,Worker),
+ Constructor(),
+ ConstructorCallWith=ScriptState,
+ RaisesException=Constructor,
+ MeasureAs=TextEncoderStreamConstructor,
+ RuntimeEnabled=EncodingStreams
+] interface TextEncoderStream {
+ readonly attribute DOMString encoding;
+ [CallWith=ScriptState, RaisesException] readonly attribute any readable;
+ [CallWith=ScriptState, RaisesException] readonly attribute any writable;
+};
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
index ef27221f757..959fa7196eb 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
@@ -18,7 +18,7 @@ MediaKeysController::MediaKeysController() = default;
WebEncryptedMediaClient* MediaKeysController::EncryptedMediaClient(
ExecutionContext* context) {
- Document* document = ToDocument(context);
+ Document* document = To<Document>(context);
WebLocalFrameImpl* web_frame =
WebLocalFrameImpl::FromFrame(document->GetFrame());
return web_frame->Client()->EncryptedMediaClient();
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
index 9a0acee798e..9f9702555d5 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_session.h"
@@ -299,11 +300,10 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
DVLOG(3) << __func__;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
- Document* document = ToDocument(execution_context);
+ Document* document = To<Document>(execution_context);
- if (!document->GetFrame() ||
- !document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kEncryptedMedia)) {
+ if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kEncryptedMedia,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document,
WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
document->AddConsoleMessage(
diff --git a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
index 65975c81c70..dc4b6094fd4 100644
--- a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
+++ b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
@@ -31,6 +31,8 @@
"modules/notifications/Notification",
"modules/payments/PaymentRequest",
"modules/peerconnection/RTCIceTransport",
+ "modules/peerconnection/RTCQuicStream",
+ "modules/peerconnection/RTCQuicTransport",
"modules/permissions/PermissionStatus",
"modules/picture_in_picture/HTMLVideoElementPictureInPicture",
"modules/picture_in_picture/PictureInPictureWindow",
@@ -41,6 +43,7 @@
"modules/remoteplayback/RemotePlayback",
"modules/screen_orientation/ScreenOrientation",
"modules/sensor/Sensor",
+ "modules/serial/Serial",
"modules/service_worker/ServiceWorker",
"modules/service_worker/ServiceWorkerContainer",
"modules/service_worker/ServiceWorkerGlobalScope",
@@ -57,6 +60,7 @@
"modules/webmidi/MIDIInput",
"modules/webmidi/MIDIPort",
"modules/xr/XR",
+ "modules/xr/XRCoordinateSystem",
"modules/xr/XRSession",
{
name: "modules/websockets/WebSocket",
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
index 8c68e3c1bd2..90eff457dd4 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -79,10 +79,9 @@ EventSource* EventSource::Create(ExecutionContext* context,
const String& url,
const EventSourceInit& event_source_init,
ExceptionState& exception_state) {
- if (context->IsDocument())
- UseCounter::Count(ToDocument(context), WebFeature::kEventSourceDocument);
- else
- UseCounter::Count(context, WebFeature::kEventSourceWorker);
+ UseCounter::Count(context, IsA<Document>(context)
+ ? WebFeature::kEventSourceDocument
+ : WebFeature::kEventSourceWorker);
if (url.IsEmpty()) {
exception_state.ThrowDOMException(
@@ -127,7 +126,7 @@ void EventSource::Connect() {
request.SetHTTPMethod(HTTPNames::GET);
request.SetHTTPHeaderField(HTTPNames::Accept, "text/event-stream");
request.SetHTTPHeaderField(HTTPNames::Cache_Control, "no-cache");
- request.SetRequestContext(WebURLRequest::kRequestContextEventSource);
+ request.SetRequestContext(mojom::RequestContextType::EVENT_SOURCE);
request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCORS);
request.SetFetchCredentialsMode(
with_credentials_ ? network::mojom::FetchCredentialsMode::kInclude
@@ -149,11 +148,8 @@ void EventSource::Connect() {
last_event_id_utf8.length()));
}
- const SecurityOrigin* origin = execution_context.GetSecurityOrigin();
-
ResourceLoaderOptions resource_loader_options;
resource_loader_options.data_buffering_policy = kDoNotBufferData;
- resource_loader_options.security_origin = origin;
probe::willSendEventSourceRequest(&execution_context, this);
loader_ =
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
index dfca4c749a7..39b80f10bec 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc
@@ -22,12 +22,12 @@ EventSourceParser::EventSourceParser(const AtomicString& last_event_id,
client_(client),
codec_(NewTextCodec(UTF8Encoding())) {}
-void EventSourceParser::AddBytes(const char* bytes, size_t size) {
+void EventSourceParser::AddBytes(const char* bytes, uint32_t size) {
// A line consists of |m_line| followed by
// |bytes[start..(next line break)]|.
- size_t start = 0;
+ uint32_t start = 0;
const unsigned char kBOM[] = {0xef, 0xbb, 0xbf};
- for (size_t i = 0; i < size && !is_stopped_; ++i) {
+ for (uint32_t i = 0; i < size && !is_stopped_; ++i) {
// As kBOM contains neither CR nor LF, we can think BOM and the line
// break separately.
if (is_recognizing_bom_ && line_.size() + (i - start) == arraysize(kBOM)) {
@@ -77,8 +77,8 @@ void EventSourceParser::ParseLine() {
event_type_ = g_null_atom;
return;
}
- size_t field_name_end = line_.Find(':');
- size_t field_value_start;
+ wtf_size_t field_name_end = line_.Find(':');
+ wtf_size_t field_value_start;
if (field_name_end == WTF::kNotFound) {
field_name_end = line_.size();
field_value_start = field_name_end;
@@ -88,7 +88,7 @@ void EventSourceParser::ParseLine() {
++field_value_start;
}
}
- size_t field_value_size = line_.size() - field_value_start;
+ wtf_size_t field_value_size = line_.size() - field_value_start;
String field_name = FromUTF8(line_.data(), field_name_end);
if (field_name == "event") {
event_type_ = AtomicString(
@@ -109,7 +109,8 @@ void EventSourceParser::ParseLine() {
}
if (field_name == "retry") {
bool has_only_digits = true;
- for (size_t i = field_value_start; i < line_.size() && has_only_digits; ++i)
+ for (wtf_size_t i = field_value_start; i < line_.size() && has_only_digits;
+ ++i)
has_only_digits = IsASCIIDigit(line_[i]);
if (field_value_start == line_.size()) {
client_->OnReconnectionTimeSet(EventSource::kDefaultReconnectDelay);
@@ -126,7 +127,7 @@ void EventSourceParser::ParseLine() {
// Unrecognized field name. Ignore!
}
-String EventSourceParser::FromUTF8(const char* bytes, size_t size) {
+String EventSourceParser::FromUTF8(const char* bytes, uint32_t size) {
return codec_->Decode(bytes, size, WTF::FlushBehavior::kDataEOF);
}
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
index 8c4ab1e72aa..e3eb4e08d8e 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT EventSourceParser final
EventSourceParser(const AtomicString& last_event_id, Client*);
- void AddBytes(const char*, size_t);
+ void AddBytes(const char*, uint32_t);
const AtomicString& LastEventId() const { return last_event_id_; }
// Stop parsing. This can be called from Client::onMessageEvent.
void Stop() { is_stopped_ = true; }
@@ -39,7 +39,7 @@ class MODULES_EXPORT EventSourceParser final
private:
void ParseLine();
- String FromUTF8(const char* bytes, size_t);
+ String FromUTF8(const char* bytes, uint32_t);
Vector<char> line_;
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
index 5da6ce1918b..2370a04f252 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/modules/eventsource/event_source.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include <string.h>
@@ -94,7 +95,9 @@ class EventSourceParserTest : public testing::Test {
parser_(new EventSourceParser(AtomicString(), client_)) {}
~EventSourceParserTest() override = default;
- void Enqueue(const char* data) { parser_->AddBytes(data, strlen(data)); }
+ void Enqueue(const char* data) {
+ parser_->AddBytes(data, static_cast<uint32_t>(strlen(data)));
+ }
void EnqueueOneByOne(const char* data) {
const char* p = data;
while (*p != '\0')
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
index 28a9aa8b13a..4f763635342 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -90,8 +90,7 @@ class WebAXSparseAttributeClientAdapter : public AXSparseAttributeClient {
void AddObjectVectorAttribute(AXObjectVectorAttribute attribute,
HeapVector<Member<AXObject>>& value) override {
WebVector<WebAXObject> result(value.size());
- for (size_t i = 0; i < value.size(); i++)
- result[i] = WebAXObject(value[i]);
+ std::copy(value.begin(), value.end(), result.begin());
attribute_map_.AddObjectVectorAttribute(
static_cast<WebAXObjectVectorAttribute>(attribute), result);
}
@@ -156,11 +155,11 @@ bool WebAXObject::UpdateLayoutAndCheckValidity() {
return !IsDetached();
}
-WebAXDefaultActionVerb WebAXObject::Action() const {
+ax::mojom::DefaultActionVerb WebAXObject::Action() const {
if (IsDetached())
- return WebAXDefaultActionVerb::kNone;
+ return ax::mojom::DefaultActionVerb::kNone;
- return static_cast<WebAXDefaultActionVerb>(private_->Action());
+ return private_->Action();
}
bool WebAXObject::CanPress() const {
@@ -239,18 +238,18 @@ WebString WebAXObject::AriaAutoComplete() const {
return private_->AriaAutoComplete();
}
-WebAXAriaCurrentState WebAXObject::AriaCurrentState() const {
+ax::mojom::AriaCurrentState WebAXObject::AriaCurrentState() const {
if (IsDetached())
- return kWebAXAriaCurrentStateUndefined;
+ return ax::mojom::AriaCurrentState::kNone;
- return static_cast<WebAXAriaCurrentState>(private_->GetAriaCurrentState());
+ return private_->GetAriaCurrentState();
}
-WebAXCheckedState WebAXObject::CheckedState() const {
+ax::mojom::CheckedState WebAXObject::CheckedState() const {
if (IsDetached())
- return kWebAXCheckedUndefined;
+ return ax::mojom::CheckedState::kNone;
- return static_cast<WebAXCheckedState>(private_->CheckedState());
+ return private_->CheckedState();
}
bool WebAXObject::IsClickable() const {
@@ -260,13 +259,6 @@ bool WebAXObject::IsClickable() const {
return private_->IsClickable();
}
-bool WebAXObject::IsCollapsed() const {
- if (IsDetached())
- return false;
-
- return private_->IsCollapsed();
-}
-
bool WebAXObject::IsControl() const {
if (IsDetached())
return false;
@@ -428,11 +420,11 @@ WebAXObject WebAXObject::AriaActiveDescendant() const {
return WebAXObject(private_->ActiveDescendant());
}
-WebAXHasPopup WebAXObject::HasPopup() const {
+ax::mojom::HasPopup WebAXObject::HasPopup() const {
if (IsDetached())
- return kWebAXHasPopupFalse;
+ return ax::mojom::HasPopup::kFalse;
- return static_cast<WebAXHasPopup>(private_->HasPopup());
+ return private_->HasPopup();
}
bool WebAXObject::IsEditableRoot() const {
@@ -581,11 +573,11 @@ WebString WebAXObject::ImageDataUrl(const WebSize& max_size) const {
return private_->ImageDataUrl(max_size);
}
-WebAXInvalidState WebAXObject::InvalidState() const {
+ax::mojom::InvalidState WebAXObject::InvalidState() const {
if (IsDetached())
- return kWebAXInvalidStateUndefined;
+ return ax::mojom::InvalidState::kNone;
- return static_cast<WebAXInvalidState>(private_->GetInvalidState());
+ return private_->GetInvalidState();
}
// Only used when invalidState() returns WebAXInvalidStateOther.
@@ -725,42 +717,53 @@ WebVector<WebAXObject> WebAXObject::RadioButtonsInGroup() const {
AXObject::AXObjectVector radio_buttons = private_->RadioButtonsInGroup();
WebVector<WebAXObject> web_radio_buttons(radio_buttons.size());
- for (size_t i = 0; i < radio_buttons.size(); ++i)
- web_radio_buttons[i] = WebAXObject(radio_buttons[i]);
+ std::copy(radio_buttons.begin(), radio_buttons.end(),
+ web_radio_buttons.begin());
return web_radio_buttons;
}
-WebAXRole WebAXObject::Role() const {
+ax::mojom::Role WebAXObject::Role() const {
if (IsDetached())
- return kWebAXRoleUnknown;
+ return ax::mojom::Role::kUnknown;
- return static_cast<WebAXRole>(private_->RoleValue());
+ return private_->RoleValue();
+}
+
+static ax::mojom::TextAffinity ToAXAffinity(TextAffinity affinity) {
+ switch (affinity) {
+ case TextAffinity::kUpstream:
+ return ax::mojom::TextAffinity::kUpstream;
+ case TextAffinity::kDownstream:
+ return ax::mojom::TextAffinity::kDownstream;
+ default:
+ NOTREACHED();
+ return ax::mojom::TextAffinity::kDownstream;
+ }
}
void WebAXObject::Selection(WebAXObject& anchor_object,
int& anchor_offset,
- WebAXTextAffinity& anchor_affinity,
+ ax::mojom::TextAffinity& anchor_affinity,
WebAXObject& focus_object,
int& focus_offset,
- WebAXTextAffinity& focus_affinity) const {
+ ax::mojom::TextAffinity& focus_affinity) const {
if (IsDetached()) {
anchor_object = WebAXObject();
anchor_offset = -1;
- anchor_affinity = kWebAXTextAffinityDownstream;
+ anchor_affinity = ax::mojom::TextAffinity::kDownstream;
focus_object = WebAXObject();
focus_offset = -1;
- focus_affinity = kWebAXTextAffinityDownstream;
+ focus_affinity = ax::mojom::TextAffinity::kDownstream;
return;
}
AXObject::AXSelection ax_selection = private_->Selection();
anchor_object = WebAXObject(ax_selection.anchor_object);
anchor_offset = ax_selection.anchor_offset;
- anchor_affinity =
- static_cast<WebAXTextAffinity>(ax_selection.anchor_affinity);
+ anchor_affinity = ToAXAffinity(ax_selection.anchor_affinity);
focus_object = WebAXObject(ax_selection.focus_object);
focus_offset = ax_selection.focus_offset;
- focus_affinity = static_cast<WebAXTextAffinity>(ax_selection.focus_affinity);
+ focus_affinity = ToAXAffinity(ax_selection.focus_affinity);
return;
}
@@ -873,18 +876,18 @@ WebString WebAXObject::StringValue() const {
return private_->StringValue();
}
-WebAXTextDirection WebAXObject::GetTextDirection() const {
+ax::mojom::TextDirection WebAXObject::GetTextDirection() const {
if (IsDetached())
- return kWebAXTextDirectionLR;
+ return ax::mojom::TextDirection::kLtr;
- return static_cast<WebAXTextDirection>(private_->GetTextDirection());
+ return private_->GetTextDirection();
}
-WebAXTextPosition WebAXObject::GetTextPosition() const {
+ax::mojom::TextPosition WebAXObject::GetTextPosition() const {
if (IsDetached())
- return kWebAXTextPositionNone;
+ return ax::mojom::TextPosition::kNone;
- return static_cast<WebAXTextPosition>(private_->GetTextPosition());
+ return private_->GetTextPosition();
}
WebAXTextStyle WebAXObject::TextStyle() const {
@@ -901,20 +904,19 @@ WebURL WebAXObject::Url() const {
return private_->Url();
}
-WebString WebAXObject::GetName(WebAXNameFrom& out_name_from,
+WebString WebAXObject::GetName(ax::mojom::NameFrom& out_name_from,
WebVector<WebAXObject>& out_name_objects) const {
if (IsDetached())
return WebString();
- AXNameFrom name_from = kAXNameFromUninitialized;
+ ax::mojom::NameFrom name_from = ax::mojom::NameFrom::kUninitialized;
HeapVector<Member<AXObject>> name_objects;
WebString result = private_->GetName(name_from, &name_objects);
- out_name_from = static_cast<WebAXNameFrom>(name_from);
+ out_name_from = name_from;
- WebVector<WebAXObject> web_name_objects(name_objects.size());
- for (size_t i = 0; i < name_objects.size(); i++)
- web_name_objects[i] = WebAXObject(name_objects[i]);
- out_name_objects.Swap(web_name_objects);
+ out_name_objects.reserve(name_objects.size());
+ out_name_objects.resize(name_objects.size());
+ std::copy(name_objects.begin(), name_objects.end(), out_name_objects.begin());
return result;
}
@@ -923,37 +925,38 @@ WebString WebAXObject::GetName() const {
if (IsDetached())
return WebString();
- AXNameFrom name_from;
+ ax::mojom::NameFrom name_from;
HeapVector<Member<AXObject>> name_objects;
return private_->GetName(name_from, &name_objects);
}
WebString WebAXObject::Description(
- WebAXNameFrom name_from,
- WebAXDescriptionFrom& out_description_from,
+ ax::mojom::NameFrom name_from,
+ ax::mojom::DescriptionFrom& out_description_from,
WebVector<WebAXObject>& out_description_objects) const {
if (IsDetached())
return WebString();
- AXDescriptionFrom description_from = kAXDescriptionFromUninitialized;
+ ax::mojom::DescriptionFrom description_from =
+ ax::mojom::DescriptionFrom::kUninitialized;
HeapVector<Member<AXObject>> description_objects;
- String result = private_->Description(static_cast<AXNameFrom>(name_from),
- description_from, &description_objects);
- out_description_from = static_cast<WebAXDescriptionFrom>(description_from);
+ String result =
+ private_->Description(name_from, description_from, &description_objects);
+ out_description_from = description_from;
- WebVector<WebAXObject> web_description_objects(description_objects.size());
- for (size_t i = 0; i < description_objects.size(); i++)
- web_description_objects[i] = WebAXObject(description_objects[i]);
- out_description_objects.Swap(web_description_objects);
+ out_description_objects.reserve(description_objects.size());
+ out_description_objects.resize(description_objects.size());
+ std::copy(description_objects.begin(), description_objects.end(),
+ out_description_objects.begin());
return result;
}
-WebString WebAXObject::Placeholder(WebAXNameFrom name_from) const {
+WebString WebAXObject::Placeholder(ax::mojom::NameFrom name_from) const {
if (IsDetached())
return WebString();
- return private_->Placeholder(static_cast<AXNameFrom>(name_from));
+ return private_->Placeholder(name_from);
}
bool WebAXObject::SupportsRangeValue() const {
@@ -1071,13 +1074,7 @@ bool WebAXObject::LineBreaks(WebVector<int>& result) const {
Vector<int> line_breaks_vector;
private_->LineBreaks(line_breaks_vector);
-
- size_t vector_size = line_breaks_vector.size();
- WebVector<int> line_breaks_web_vector(vector_size);
- for (size_t i = 0; i < vector_size; i++)
- line_breaks_web_vector[i] = line_breaks_vector[i];
- result.Swap(line_breaks_web_vector);
-
+ result = line_breaks_vector;
return true;
}
@@ -1164,21 +1161,16 @@ void WebAXObject::RowHeaders(
AXObject::AXObjectVector headers;
private_->RowHeaders(headers);
-
- size_t header_count = headers.size();
- WebVector<WebAXObject> result(header_count);
-
- for (size_t i = 0; i < header_count; i++)
- result[i] = WebAXObject(headers[i]);
-
- row_header_elements.Swap(result);
+ row_header_elements.reserve(headers.size());
+ row_header_elements.resize(headers.size());
+ std::copy(headers.begin(), headers.end(), row_header_elements.begin());
}
unsigned WebAXObject::ColumnIndex() const {
if (IsDetached())
return 0;
- if (private_->RoleValue() != kColumnRole)
+ if (private_->RoleValue() != ax::mojom::Role::kColumn)
return 0;
return private_->ColumnIndex();
@@ -1188,7 +1180,7 @@ WebAXObject WebAXObject::ColumnHeader() const {
if (IsDetached())
return WebAXObject();
- if (private_->RoleValue() != kColumnRole)
+ if (private_->RoleValue() != ax::mojom::Role::kColumn)
return WebAXObject();
return WebAXObject(private_->HeaderObject());
@@ -1204,14 +1196,9 @@ void WebAXObject::ColumnHeaders(
AXObject::AXObjectVector headers;
private_->ColumnHeaders(headers);
-
- size_t header_count = headers.size();
- WebVector<WebAXObject> result(header_count);
-
- for (size_t i = 0; i < header_count; i++)
- result[i] = WebAXObject(headers[i]);
-
- column_header_elements.Swap(result);
+ column_header_elements.reserve(headers.size());
+ column_header_elements.resize(headers.size());
+ std::copy(headers.begin(), headers.end(), column_header_elements.begin());
}
unsigned WebAXObject::CellColumnIndex() const {
@@ -1242,11 +1229,11 @@ unsigned WebAXObject::CellRowSpan() const {
return private_->IsTableCellLikeRole() ? private_->RowSpan() : 0;
}
-WebAXSortDirection WebAXObject::SortDirection() const {
+ax::mojom::SortDirection WebAXObject::SortDirection() const {
if (IsDetached())
- return kWebAXSortDirectionUndefined;
+ return ax::mojom::SortDirection::kNone;
- return static_cast<WebAXSortDirection>(private_->GetSortDirection());
+ return private_->GetSortDirection();
}
void WebAXObject::LoadInlineTextBoxes() const {
@@ -1270,7 +1257,25 @@ WebAXObject WebAXObject::PreviousOnLine() const {
return WebAXObject(private_.Get()->PreviousOnLine());
}
-void WebAXObject::Markers(WebVector<WebAXMarkerType>& types,
+static ax::mojom::MarkerType ToAXMarkerType(
+ DocumentMarker::MarkerType marker_type) {
+ switch (marker_type) {
+ case DocumentMarker::kSpelling:
+ return ax::mojom::MarkerType::kSpelling;
+ case DocumentMarker::kGrammar:
+ return ax::mojom::MarkerType::kGrammar;
+ case DocumentMarker::kTextMatch:
+ return ax::mojom::MarkerType::kTextMatch;
+ case DocumentMarker::kActiveSuggestion:
+ return ax::mojom::MarkerType::kActiveSuggestion;
+ case DocumentMarker::kSuggestion:
+ return ax::mojom::MarkerType::kSuggestion;
+ default:
+ return ax::mojom::MarkerType::kNone;
+ }
+}
+
+void WebAXObject::Markers(WebVector<ax::mojom::MarkerType>& types,
WebVector<int>& starts,
WebVector<int>& ends) const {
if (IsDetached())
@@ -1281,11 +1286,11 @@ void WebAXObject::Markers(WebVector<WebAXMarkerType>& types,
private_->Markers(marker_types, marker_ranges);
DCHECK_EQ(marker_types.size(), marker_ranges.size());
- WebVector<WebAXMarkerType> web_marker_types(marker_types.size());
+ WebVector<ax::mojom::MarkerType> web_marker_types(marker_types.size());
WebVector<int> start_offsets(marker_ranges.size());
WebVector<int> end_offsets(marker_ranges.size());
- for (size_t i = 0; i < marker_types.size(); ++i) {
- web_marker_types[i] = static_cast<WebAXMarkerType>(marker_types[i]);
+ for (wtf_size_t i = 0; i < marker_types.size(); ++i) {
+ web_marker_types[i] = ToAXMarkerType(marker_types[i]);
DCHECK(marker_ranges[i].IsValid());
DCHECK_EQ(marker_ranges[i].Start().ContainerObject(),
marker_ranges[i].End().ContainerObject());
@@ -1304,12 +1309,7 @@ void WebAXObject::CharacterOffsets(WebVector<int>& offsets) const {
Vector<int> offsets_vector;
private_->TextCharacterOffsets(offsets_vector);
-
- size_t vector_size = offsets_vector.size();
- WebVector<int> offsets_web_vector(vector_size);
- for (size_t i = 0; i < vector_size; i++)
- offsets_web_vector[i] = offsets_vector[i];
- offsets.Swap(offsets_web_vector);
+ offsets = offsets_vector;
}
void WebAXObject::GetWordBoundaries(WebVector<int>& starts,
@@ -1322,7 +1322,7 @@ void WebAXObject::GetWordBoundaries(WebVector<int>& starts,
WebVector<int> word_start_offsets(word_boundaries.size());
WebVector<int> word_end_offsets(word_boundaries.size());
- for (size_t i = 0; i < word_boundaries.size(); ++i) {
+ for (wtf_size_t i = 0; i < word_boundaries.size(); ++i) {
DCHECK(word_boundaries[i].IsValid());
DCHECK_EQ(word_boundaries[i].Start().ContainerObject(),
word_boundaries[i].End().ContainerObject());
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
index 7c24cfabb2a..fed359691e4 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
@@ -89,20 +89,20 @@ WebString WebDOMFileSystem::GetName() const {
return private_->name();
}
-WebFileSystem::Type WebDOMFileSystem::GetType() const {
+WebFileSystemType WebDOMFileSystem::GetType() const {
DCHECK(private_.Get());
switch (private_->GetType()) {
case blink::mojom::FileSystemType::kTemporary:
- return WebFileSystem::kTypeTemporary;
+ return WebFileSystemType::kWebFileSystemTypeTemporary;
case blink::mojom::FileSystemType::kPersistent:
- return WebFileSystem::kTypePersistent;
+ return WebFileSystemType::kWebFileSystemTypePersistent;
case blink::mojom::FileSystemType::kIsolated:
- return WebFileSystem::kTypeIsolated;
+ return WebFileSystemType::kWebFileSystemTypeIsolated;
case blink::mojom::FileSystemType::kExternal:
- return WebFileSystem::kTypeExternal;
+ return WebFileSystemType::kWebFileSystemTypeExternal;
default:
NOTREACHED();
- return WebFileSystem::kTypeTemporary;
+ return WebFileSystemType::kWebFileSystemTypeTemporary;
}
}
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index 360d0299fe6..cd9cda55dd5 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -32,8 +32,10 @@
#include <memory>
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.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_provider.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
@@ -55,7 +57,6 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_inspector_proxy.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db_client.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_container_client.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
@@ -66,22 +67,25 @@
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+// static
std::unique_ptr<WebEmbeddedWorker> WebEmbeddedWorker::Create(
std::unique_ptr<WebServiceWorkerContextClient> client,
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager>
- installed_scripts_manager,
+ std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>
+ installed_scripts_manager_params,
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle cache_storage,
mojo::ScopedMessagePipeHandle interface_provider) {
return std::make_unique<WebEmbeddedWorkerImpl>(
- std::move(client), std::move(installed_scripts_manager),
+ std::move(client), std::move(installed_scripts_manager_params),
std::make_unique<ServiceWorkerContentSettingsProxy>(
// Chrome doesn't use interface versioning.
// TODO(falken): Is that comment about versioning correct?
@@ -94,10 +98,25 @@ std::unique_ptr<WebEmbeddedWorker> WebEmbeddedWorker::Create(
service_manager::mojom::blink::InterfaceProvider::Version_));
}
+// static
+std::unique_ptr<WebEmbeddedWorkerImpl> WebEmbeddedWorkerImpl::CreateForTesting(
+ std::unique_ptr<WebServiceWorkerContextClient> client,
+ std::unique_ptr<ServiceWorkerInstalledScriptsManager>
+ installed_scripts_manager) {
+ auto worker_impl = std::make_unique<WebEmbeddedWorkerImpl>(
+ std::move(client), nullptr /* installed_scripts_manager_params */,
+ std::make_unique<ServiceWorkerContentSettingsProxy>(
+ nullptr /* host_info */),
+ nullptr /* cache_storage_info */, nullptr /* interface_provider_info */);
+ worker_impl->installed_scripts_manager_ =
+ std::move(installed_scripts_manager);
+ return worker_impl;
+}
+
WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl(
std::unique_ptr<WebServiceWorkerContextClient> client,
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager>
- installed_scripts_manager,
+ std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>
+ installed_scripts_manager_params,
std::unique_ptr<ServiceWorkerContentSettingsProxy> content_settings_client,
mojom::blink::CacheStoragePtrInfo cache_storage_info,
service_manager::mojom::blink::InterfaceProviderPtrInfo
@@ -109,10 +128,22 @@ WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl(
waiting_for_debugger_state_(kNotWaitingForDebugger),
cache_storage_info_(std::move(cache_storage_info)),
interface_provider_info_(std::move(interface_provider_info)) {
- if (installed_scripts_manager) {
- installed_scripts_manager_ =
- std::make_unique<ServiceWorkerInstalledScriptsManager>(
- std::move(installed_scripts_manager));
+ if (installed_scripts_manager_params) {
+ DCHECK(installed_scripts_manager_params->manager_request.is_valid());
+ DCHECK(installed_scripts_manager_params->manager_host_ptr.is_valid());
+ Vector<KURL> installed_scripts_urls;
+ installed_scripts_urls.AppendRange(
+ installed_scripts_manager_params->installed_scripts_urls.begin(),
+ installed_scripts_manager_params->installed_scripts_urls.end());
+ installed_scripts_manager_ = std::make_unique<
+ ServiceWorkerInstalledScriptsManager>(
+ installed_scripts_urls,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerRequest(
+ std::move(installed_scripts_manager_params->manager_request)),
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHostPtrInfo(
+ std::move(installed_scripts_manager_params->manager_host_ptr),
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHost::Version_),
+ Platform::Current()->GetIOTaskRunner());
}
}
@@ -239,9 +270,14 @@ void WebEmbeddedWorkerImpl::AddMessageToConsole(
}
void WebEmbeddedWorkerImpl::BindDevToolsAgent(
+ mojo::ScopedInterfaceEndpointHandle devtools_agent_host_ptr_info,
mojo::ScopedInterfaceEndpointHandle devtools_agent_request) {
- shadow_page_->BindDevToolsAgent(mojom::blink::DevToolsAgentAssociatedRequest(
- std::move(devtools_agent_request)));
+ shadow_page_->DevToolsAgent()->BindRequest(
+ mojom::blink::DevToolsAgentHostAssociatedPtrInfo(
+ std::move(devtools_agent_host_ptr_info),
+ mojom::blink::DevToolsAgentHost::Version_),
+ mojom::blink::DevToolsAgentAssociatedRequest(
+ std::move(devtools_agent_request)));
}
void WebEmbeddedWorkerImpl::PostMessageToPageInspector(int session_id,
@@ -280,7 +316,7 @@ void WebEmbeddedWorkerImpl::OnShadowPageInitialized() {
main_script_loader_ = WorkerClassicScriptLoader::Create();
main_script_loader_->LoadTopLevelScriptAsynchronously(
*shadow_page_->GetDocument(), worker_start_data_.script_url,
- WebURLRequest::kRequestContextServiceWorker,
+ mojom::RequestContextType::SERVICE_WORKER,
network::mojom::FetchRequestMode::kSameOrigin,
network::mojom::FetchCredentialsMode::kSameOrigin,
worker_start_data_.address_space, base::OnceClosure(),
@@ -340,8 +376,6 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
ProvideServiceWorkerGlobalScopeClientToWorker(
worker_clients,
new ServiceWorkerGlobalScopeClient(*worker_context_client_));
- ProvideServiceWorkerContainerClientToWorker(
- worker_clients, worker_context_client_->CreateServiceWorkerProvider());
std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context =
worker_context_client_->CreateServiceWorkerFetchContext(
@@ -359,9 +393,13 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
String source_code;
std::unique_ptr<Vector<char>> cached_meta_data;
- // TODO(nhiroki); Set |script_type| to ScriptType::kModule for module fetch.
- // (https://crbug.com/824647)
- ScriptType script_type = ScriptType::kClassic;
+ // TODO(https://crbug.com/824647): Use blink::mojom::ScriptType everywhere
+ // and deprecate blink::ScriptType.
+ // Remove this line after removed all blink::ScriptType.
+ ScriptType script_type =
+ (worker_start_data_.script_type == mojom::ScriptType::kModule)
+ ? ScriptType::kModule
+ : ScriptType::kClassic;
// |main_script_loader_| isn't created if the InstalledScriptsManager had the
// script.
@@ -426,13 +464,34 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
worker_inspector_proxy_->WorkerThreadCreated(document, worker_thread_.get(),
worker_start_data_.script_url);
- // TODO(nhiroki): Support module workers (https://crbug.com/680046).
- // Note that this doesn't really start the script evaluation until
- // ReadyToEvaluateScript() is called on the WebServiceWorkerContextProxy
- // on the worker thread.
- worker_thread_->EvaluateClassicScript(
- worker_start_data_.script_url, source_code, std::move(cached_meta_data),
- v8_inspector::V8StackTraceId());
+ // > Switching on job’s worker type, run these substeps with the following
+ // > options:
+ // https://w3c.github.io/ServiceWorker/#update-algorithm
+ if (script_type == ScriptType::kClassic) {
+ // > "classic": Fetch a classic worker script given job’s serialized script
+ // > url, job’s client, "serviceworker", and the to-be-created environment
+ // > settings object for this service worker.
+ // Service worker is origin-bound, so use kSharableCrossOrigin.
+ worker_thread_->EvaluateClassicScript(
+ worker_start_data_.script_url, kSharableCrossOrigin, source_code,
+ std::move(cached_meta_data), v8_inspector::V8StackTraceId());
+ } else {
+ // > "module": Fetch a module worker script graph given job’s serialized
+ // > script url, job’s client, "serviceworker", "omit", and the
+ // > to-be-created environment settings object for this service worker.
+
+ // TODO(asamidoi): Currently, we use the shadow page's Document as an
+ // outside_settings_object as a workaround. This should be the Document that
+ // called navigator.ServiceWorker.register(). To do it, we need to make a
+ // way to pass the settings object over mojo IPCs.
+ auto* outside_settings_object =
+ document->CreateFetchClientSettingsObjectSnapshot();
+ network::mojom::FetchCredentialsMode credentials_mode =
+ network::mojom::FetchCredentialsMode::kOmit;
+ worker_thread_->ImportModuleScript(worker_start_data_.script_url,
+ outside_settings_object,
+ credentials_mode);
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
index ffb8994e780..7c73402d511 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
+++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
@@ -59,7 +59,7 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
public:
WebEmbeddedWorkerImpl(
std::unique_ptr<WebServiceWorkerContextClient>,
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager>,
+ std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>,
std::unique_ptr<ServiceWorkerContentSettingsProxy>,
mojom::blink::CacheStoragePtrInfo,
service_manager::mojom::blink::InterfaceProviderPtrInfo);
@@ -71,6 +71,7 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
void ResumeAfterDownload() override;
void AddMessageToConsole(const WebConsoleMessage&) override;
void BindDevToolsAgent(
+ mojo::ScopedInterfaceEndpointHandle devtools_agent_host_ptr_info,
mojo::ScopedInterfaceEndpointHandle devtools_agent_request) override;
void PostMessageToPageInspector(int session_id, const WTF::String&);
@@ -80,6 +81,10 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
WebApplicationCacheHostClient*) override;
void OnShadowPageInitialized() override;
+ static std::unique_ptr<WebEmbeddedWorkerImpl> CreateForTesting(
+ std::unique_ptr<WebServiceWorkerContextClient>,
+ std::unique_ptr<ServiceWorkerInstalledScriptsManager>);
+
private:
// WebDevToolsAgentImpl::Client overrides.
void ResumeStartup() override;
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_idb_key.cc b/chromium/third_party/blink/renderer/modules/exported/web_idb_key.cc
index 9b183328b2b..600bfce5080 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_idb_key.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_idb_key.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
@@ -36,7 +37,7 @@ size_t WebIDBKeyArrayView::size() const {
}
WebIDBKeyView WebIDBKeyArrayView::operator[](size_t index) const {
- return WebIDBKeyView(private_->Array()[index].get());
+ return WebIDBKeyView(private_->Array()[SafeCast<wtf_size_t>(index)].get());
}
WebIDBKeyType WebIDBKeyView::KeyType() const {
@@ -69,7 +70,7 @@ double WebIDBKeyView::Number() const {
WebIDBKey WebIDBKey::CreateArray(WebVector<WebIDBKey> array) {
IDBKey::KeyArray keys;
- keys.ReserveCapacity(array.size());
+ keys.ReserveCapacity(SafeCast<wtf_size_t>(array.size()));
for (WebIDBKey& key : array) {
DCHECK(key.View().KeyType() != kWebIDBKeyTypeNull);
keys.emplace_back(key.ReleaseIdbKey());
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
index 2e158d69650..021534621b5 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
@@ -49,6 +49,10 @@ blink_modules_sources("filesystem") {
"file_system_client.h",
"file_system_directory_handle.cc",
"file_system_directory_handle.h",
+ "file_system_directory_iterator.cc",
+ "file_system_directory_iterator.h",
+ "file_system_dispatcher.cc",
+ "file_system_dispatcher.h",
"file_system_file_handle.cc",
"file_system_file_handle.h",
"file_system_writer.cc",
@@ -70,4 +74,9 @@ blink_modules_sources("filesystem") {
"worker_global_scope_file_system.cc",
"worker_global_scope_file_system.h",
]
+
+ deps = [
+ "//components/services/filesystem/public/interfaces:interfaces_blink",
+ "//third_party/blink/renderer/platform",
+ ]
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/DEPS b/chromium/third_party/blink/renderer/modules/filesystem/DEPS
index 6bec426b0d2..e8bdd831680 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/DEPS
+++ b/chromium/third_party/blink/renderer/modules/filesystem/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+base/files/file.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_target_modules.h",
"+third_party/blink/renderer/modules/filesystem",
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/OWNERS b/chromium/third_party/blink/renderer/modules/filesystem/OWNERS
index a4c6d78bad6..373163caefd 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/filesystem/OWNERS
@@ -1,3 +1,4 @@
+mek@chromium.org
jsbell@chromium.org
kinuko@chromium.org
pwnall@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/README.md b/chromium/third_party/blink/renderer/modules/filesystem/README.md
new file mode 100644
index 00000000000..6e3f3df6d52
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/README.md
@@ -0,0 +1,74 @@
+# FileSystem API
+
+This directory contains the renderer side implementation of various filesystem
+related APIs.
+
+## Related directories
+
+[`//storage/browser/fileapi/`](../../../storage/browser/fileapi) contains part
+of the browser side implementation, while
+[`//content/browser/fileapi/`](../../../content/browser/fileapi) contains the
+rest of the browser side implementation and
+[`blink/public/mojom/filesystem`](../../../third_party/blink/public/mojom/filesystem)
+contains the mojom interfaces for these APIs.
+
+## APIs In this directory
+
+### File and Directory Entries API
+
+First of all this directory contains the implementation of the
+[Entries API](https://wicg.github.io/entries-api). This API consists of
+types to expose read-only access to file and directory entries to the web,
+primarily used by drag-and-drop and `<input type=file>`. Our implementation
+doesn't match the interface names of the spec, but otherwise should be pretty
+close to the spec.
+
+TODO(mek): More details
+
+### File API: Directories and FileSystem
+
+Secondly this directory contains the implementation of something similar to the
+deprecated [w3c file-system-api](https://www.w3.org/TR/2012/WD-file-system-api-20120417/).
+This API is very similar to the previous Entries API, but it also adds support
+for writing and modifying to files and directories, as well as a way to get
+access to a origin scoped sandboxed filesystem.
+
+TODO(mek): More details
+
+### Writable Files
+
+Finally this directory contains the implementation of the new and still under
+development [Writable Files API](https://github.com/WICG/writable-files/blob/master/EXPLAINER.md).
+This API is mostly implemented on top of the same backend as the previous two
+APIs, but hopes to eventually replace both of those, while also adding new
+functionality.
+
+It consists of the following parts:
+
+ * `FileSystemBaseHandle`, `FileSystemFileHandle` and `FileSystemDirectoryHandle`:
+ these interfaces mimic the old `Entry` interfaces (and inherit from `EntryBase`
+ to share as much of the implementation as possible), but expose a more modern
+ promisified API.
+
+ * `getSystemDirectory`: An entry point (exposed via `FileSystemDirectoryHandle`)
+ that today only gives access to the same sandboxed filesystem as what was
+ available through the old API. In the future this could get extended to add
+ support for other directories as well.
+
+ * `FileSystemWriter`: a more modern API with similar functionality to the
+ old `FileWriter` API. The implementation of this actually does make use of
+ a different mojom interface than the old API. But since the functionality is
+ mostly the same, hopefully we will be able to migrate the old implementation
+ to the new mojom API as well.
+
+ * `chooseFileSystemEntries`: An entry point, currently on `window`, that lets
+ a website pop-up a file picker, prompting the user to select one or more
+ files or directories, to which the website than gets access.
+
+Since the `Handle` interfaces are based on the implementation of the `Entry`
+interfaces, internally and across IPC these are still represented by
+`filesystem://` URLs. Hopefully in the future we will be able to change this and
+turn it into a more capabilities based API (where having a mojo handle gives you
+access to specific files or directories), as with the current implementation it
+is very hard to properly support transferring handles to other processes via
+postMessage (which is something we do want to support in the future).
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options.idl b/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options.idl
new file mode 100644
index 00000000000..9907820a2af
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options.idl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/writable-files/#enumdef-choosefilesystementriestype
+enum ChooseFileSystemEntriesType { "openFile", "saveFile", "openDirectory" };
+
+// https://wicg.github.io/writable-files/#dictdef-choosefilesystementriesoptions
+dictionary ChooseFileSystemEntriesOptions {
+ ChooseFileSystemEntriesType type = "openFile";
+ boolean multiple = false;
+ sequence<ChooseFileSystemEntriesOptionsAccepts> accepts;
+ boolean excludeAcceptAllOption = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options_accepts.idl b/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options_accepts.idl
new file mode 100644
index 00000000000..6b95a2b240d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options_accepts.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+dictionary ChooseFileSystemEntriesOptionsAccepts {
+ DOMString description;
+ sequence<DOMString> mimeTypes;
+ sequence<DOMString> extensions;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
index 607b4444dae..e234149591b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
@@ -77,7 +77,7 @@ class DirectoryReader::ErrorCallbackHelper final : public ErrorCallbackBase {
return new ErrorCallbackHelper(reader);
}
- void Invoke(FileError::ErrorCode error) override { reader_->OnError(error); }
+ void Invoke(base::File::Error error) override { reader_->OnError(error); }
void Trace(blink::Visitor* visitor) override {
visitor->Trace(reader_);
@@ -103,7 +103,7 @@ void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
ErrorCallbackHelper::Create(this));
}
- if (error_) {
+ if (error_ != base::File::FILE_OK) {
Filesystem()->ReportError(ScriptErrorCallback::Wrap(error_callback),
error_);
return;
@@ -113,7 +113,7 @@ void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
// Non-null entries_callback_ means multiple readEntries() calls are made
// concurrently. We don't allow doing it.
Filesystem()->ReportError(ScriptErrorCallback::Wrap(error_callback),
- FileError::kInvalidStateErr);
+ base::File::FILE_ERROR_FAILED);
return;
}
@@ -142,7 +142,7 @@ void DirectoryReader::AddEntries(const EntryHeapVector& entries) {
}
}
-void DirectoryReader::OnError(FileError::ErrorCode error) {
+void DirectoryReader::OnError(base::File::Error error) {
error_ = error;
entries_callback_ = nullptr;
if (auto* error_callback = error_callback_.Release()) {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
index c0e5240abdb..aa741253d1d 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h
@@ -67,11 +67,11 @@ class DirectoryReader : public DirectoryReaderBase {
void AddEntries(const EntryHeapVector& entries);
- void OnError(FileError::ErrorCode);
+ void OnError(base::File::Error error);
bool is_reading_;
EntryHeapVector entries_;
- FileError::ErrorCode error_ = FileError::ErrorCode::kOK;
+ base::File::Error error_ = base::File::FILE_OK;
Member<V8PersistentCallbackInterface<V8EntriesCallback>> entries_callback_;
Member<V8PersistentCallbackInterface<V8ErrorCallback>> error_callback_;
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
index 7bed6982573..1e7d48d50cb 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc
@@ -78,7 +78,7 @@ class DirectoryReaderSync::ErrorCallbackHelper final
ErrorCallbackBase::Trace(visitor);
}
- void Invoke(FileError::ErrorCode error) override {
+ void Invoke(base::File::Error error) override {
reader_->error_code_ = error;
}
@@ -94,15 +94,16 @@ DirectoryReaderSync::DirectoryReaderSync(DOMFileSystemBase* file_system,
EntrySyncHeapVector DirectoryReaderSync::readEntries(
ExceptionState& exception_state) {
- if (!callbacks_id_) {
- callbacks_id_ = Filesystem()->ReadDirectory(
+ if (!has_called_read_directory_) {
+ Filesystem()->ReadDirectory(
this, full_path_, EntriesCallbackHelper::Create(this),
ErrorCallbackHelper::Create(this), DOMFileSystemBase::kSynchronous);
+ has_called_read_directory_ = true;
}
DCHECK(!has_more_entries_);
- if (error_code_ != FileError::kOK) {
+ if (error_code_ != base::File::FILE_OK) {
FileError::ThrowDOMException(exception_state, error_code_);
return EntrySyncHeapVector();
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
index 3e97b4e59b1..92b1bedab3f 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h
@@ -64,9 +64,9 @@ class DirectoryReaderSync : public DirectoryReaderBase {
DirectoryReaderSync(DOMFileSystemBase*, const String& full_path);
- int callbacks_id_ = 0;
+ bool has_called_read_directory_ = false;
EntrySyncHeapVector entries_;
- FileError::ErrorCode error_code_ = FileError::kOK;
+ base::File::Error error_code_ = base::File::FILE_OK;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_path.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_path.cc
index c50c536d052..d1ca3514469 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_path.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_path.cc
@@ -83,22 +83,22 @@ String DOMFilePath::RemoveExtraParentReferences(const String& path) {
Vector<String> components;
Vector<String> canonicalized;
path.Split(DOMFilePath::kSeparator, components);
- for (size_t i = 0; i < components.size(); ++i) {
- if (components[i] == ".")
+ for (const auto& component : components) {
+ if (component == ".")
continue;
- if (components[i] == "..") {
+ if (component == "..") {
if (canonicalized.size() > 0)
canonicalized.pop_back();
continue;
}
- canonicalized.push_back(components[i]);
+ canonicalized.push_back(component);
}
if (canonicalized.IsEmpty())
return DOMFilePath::kRoot;
StringBuilder result;
- for (size_t i = 0; i < canonicalized.size(); ++i) {
+ for (const auto& component : canonicalized) {
result.Append(DOMFilePath::kSeparator);
- result.Append(canonicalized[i]);
+ result.Append(component);
}
return result.ToString();
}
@@ -120,13 +120,10 @@ bool DOMFilePath::IsValidPath(const String& path) {
// ".." or "." is likely an attempt to break out of the sandbox.
Vector<String> components;
path.Split(DOMFilePath::kSeparator, components);
- for (size_t i = 0; i < components.size(); ++i) {
- if (components[i] == ".")
- return false;
- if (components[i] == "..")
- return false;
- }
- return true;
+ return std::none_of(components.begin(), components.end(),
+ [](const String& component) {
+ return component == "." || component == "..";
+ });
}
bool DOMFilePath::IsValidName(const String& name) {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
index 5e5f3e8e37b..9d079872924 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
@@ -33,14 +33,13 @@
#include <memory>
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_file_system.h"
-#include "third_party/blink/public/platform/web_file_system_callbacks.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/filesystem/directory_entry.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_path.h"
#include "third_party/blink/renderer/modules/filesystem/file_entry.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -126,18 +125,18 @@ bool DOMFileSystem::HasPendingActivity() const {
}
void DOMFileSystem::ReportError(ErrorCallbackBase* error_callback,
- FileError::ErrorCode file_error) {
- ReportError(GetExecutionContext(), error_callback, file_error);
+ base::File::Error error) {
+ ReportError(GetExecutionContext(), error_callback, error);
}
void DOMFileSystem::ReportError(ExecutionContext* execution_context,
ErrorCallbackBase* error_callback,
- FileError::ErrorCode file_error) {
+ base::File::Error error) {
if (!error_callback)
return;
ScheduleCallback(execution_context,
WTF::Bind(&ErrorCallbackBase::Invoke,
- WrapPersistent(error_callback), file_error));
+ WrapPersistent(error_callback), error));
}
void DOMFileSystem::CreateWriter(
@@ -146,17 +145,12 @@ void DOMFileSystem::CreateWriter(
ErrorCallbackBase* error_callback) {
DCHECK(file_entry);
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
FileWriter* file_writer = FileWriter::Create(GetExecutionContext());
std::unique_ptr<AsyncFileSystemCallbacks> callbacks =
FileWriterCallbacks::Create(file_writer, success_callback, error_callback,
context_);
- FileSystem()->CreateFileWriter(CreateFileSystemURL(file_entry), file_writer,
- std::move(callbacks));
+ FileSystemDispatcher::From(context_).InitializeFileWriter(
+ CreateFileSystemURL(file_entry), std::move(callbacks));
}
void DOMFileSystem::CreateFile(
@@ -164,12 +158,8 @@ void DOMFileSystem::CreateFile(
SnapshotFileCallback::OnDidCreateSnapshotFileCallback* success_callback,
ErrorCallbackBase* error_callback) {
KURL file_system_url = CreateFileSystemURL(file_entry);
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
- FileSystem()->CreateSnapshotFileAndReadMetadata(
+ FileSystemDispatcher::From(context_).CreateSnapshotFile(
file_system_url,
SnapshotFileCallback::Create(this, file_entry->name(), file_system_url,
success_callback, error_callback, context_));
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
index a1e90d31579..465c3f5776e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h
@@ -67,11 +67,11 @@ class MODULES_EXPORT DOMFileSystem final
// DOMFileSystemBase overrides.
void AddPendingCallbacks() override;
void RemovePendingCallbacks() override;
- void ReportError(ErrorCallbackBase*, FileError::ErrorCode) override;
+ void ReportError(ErrorCallbackBase*, base::File::Error error) override;
static void ReportError(ExecutionContext*,
ErrorCallbackBase*,
- FileError::ErrorCode);
+ base::File::Error error);
// ScriptWrappable overrides.
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
index c8e148aad92..98e1a6566c8 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -32,8 +32,6 @@
#include <memory>
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_file_system.h"
-#include "third_party/blink/public/platform/web_file_system_callbacks.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
@@ -44,6 +42,7 @@
#include "third_party/blink/renderer/modules/filesystem/entry.h"
#include "third_party/blink/renderer/modules/filesystem/entry_base.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -73,13 +72,6 @@ void DOMFileSystemBase::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-WebFileSystem* DOMFileSystemBase::FileSystem() const {
- Platform* platform = Platform::Current();
- if (!platform)
- return nullptr;
- return platform->FileSystem();
-}
-
const SecurityOrigin* DOMFileSystemBase::GetSecurityOrigin() const {
return context_->GetSecurityOrigin();
}
@@ -217,15 +209,16 @@ void DOMFileSystemBase::GetMetadata(
MetadataCallbacks::OnDidReadMetadataCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(MetadataCallbacks::Create(
success_callback, error_callback, context_, this));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
- FileSystem()->ReadMetadata(CreateFileSystemURL(entry), std::move(callbacks));
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+
+ if (synchronous_type == kSynchronous) {
+ dispatcher.ReadMetadataSync(CreateFileSystemURL(entry),
+ std::move(callbacks));
+ } else {
+ dispatcher.ReadMetadata(CreateFileSystemURL(entry), std::move(callbacks));
+ }
}
static bool VerifyAndGetDestinationPathForCopyOrMove(const EntryBase* source,
@@ -272,27 +265,25 @@ void DOMFileSystemBase::Move(
EntryCallbacks::OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
String destination_path;
if (!VerifyAndGetDestinationPathForCopyOrMove(source, parent, new_name,
destination_path)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create(
success_callback, error_callback, context_, parent->filesystem(),
destination_path, source->isDirectory()));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
- FileSystem()->Move(
- CreateFileSystemURL(source),
- parent->filesystem()->CreateFileSystemURL(destination_path),
- std::move(callbacks));
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+ const KURL& src = CreateFileSystemURL(source);
+ const KURL& dest =
+ parent->filesystem()->CreateFileSystemURL(destination_path);
+ if (synchronous_type == kSynchronous)
+ dispatcher.MoveSync(src, dest, std::move(callbacks));
+ else
+ dispatcher.Move(src, dest, std::move(callbacks));
}
void DOMFileSystemBase::Copy(
@@ -302,27 +293,25 @@ void DOMFileSystemBase::Copy(
EntryCallbacks::OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
String destination_path;
if (!VerifyAndGetDestinationPathForCopyOrMove(source, parent, new_name,
destination_path)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create(
success_callback, error_callback, context_, parent->filesystem(),
destination_path, source->isDirectory()));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
- FileSystem()->Copy(
- CreateFileSystemURL(source),
- parent->filesystem()->CreateFileSystemURL(destination_path),
- std::move(callbacks));
+ const KURL& src = CreateFileSystemURL(source);
+ const KURL& dest =
+ parent->filesystem()->CreateFileSystemURL(destination_path);
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+ if (synchronous_type == kSynchronous)
+ dispatcher.CopySync(src, dest, std::move(callbacks));
+ else
+ dispatcher.Copy(src, dest, std::move(callbacks));
}
void DOMFileSystemBase::Remove(
@@ -330,23 +319,21 @@ void DOMFileSystemBase::Remove(
VoidCallbacks::OnDidSucceedCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
DCHECK(entry);
// We don't allow calling remove() on the root directory.
if (entry->fullPath() == String(DOMFilePath::kRoot)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(
VoidCallbacks::Create(success_callback, error_callback, context_, this));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
-
- FileSystem()->Remove(CreateFileSystemURL(entry), std::move(callbacks));
+ const KURL& url = CreateFileSystemURL(entry);
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+ if (synchronous_type == kSynchronous)
+ dispatcher.RemoveSync(url, /*recursive=*/false, std::move(callbacks));
+ else
+ dispatcher.Remove(url, /*recursive=*/false, std::move(callbacks));
}
void DOMFileSystemBase::RemoveRecursively(
@@ -354,41 +341,33 @@ void DOMFileSystemBase::RemoveRecursively(
VoidCallbacks::OnDidSucceedCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
DCHECK(entry);
DCHECK(entry->isDirectory());
// We don't allow calling remove() on the root directory.
if (entry->fullPath() == String(DOMFilePath::kRoot)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(
VoidCallbacks::Create(success_callback, error_callback, context_, this));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
-
- FileSystem()->RemoveRecursively(CreateFileSystemURL(entry),
- std::move(callbacks));
+ const KURL& url = CreateFileSystemURL(entry);
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+ if (synchronous_type == kSynchronous)
+ dispatcher.RemoveSync(url, /*recursive=*/true, std::move(callbacks));
+ else
+ dispatcher.Remove(url, /*recursive=*/true, std::move(callbacks));
}
void DOMFileSystemBase::GetParent(
const EntryBase* entry,
EntryCallbacks::OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
DCHECK(entry);
String path = DOMFilePath::GetDirectory(entry->fullPath());
- FileSystem()->DirectoryExists(
- CreateFileSystemURL(path),
+ FileSystemDispatcher::From(context_).Exists(
+ CreateFileSystemURL(path), /*is_directory=*/true,
EntryCallbacks::Create(success_callback, error_callback, context_, this,
path, true));
}
@@ -400,27 +379,29 @@ void DOMFileSystemBase::GetFile(
EntryCallbacks::OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
String absolute_path;
if (!PathToAbsolutePath(type_, entry, path, absolute_path)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create(
success_callback, error_callback, context_, this, absolute_path, false));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
-
- if (flags.createFlag())
- FileSystem()->CreateFile(CreateFileSystemURL(absolute_path),
- flags.exclusive(), std::move(callbacks));
- else
- FileSystem()->FileExists(CreateFileSystemURL(absolute_path),
- std::move(callbacks));
+ const KURL& url = CreateFileSystemURL(absolute_path);
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+
+ if (flags.createFlag()) {
+ if (synchronous_type == kSynchronous)
+ dispatcher.CreateFileSync(url, flags.exclusive(), std::move(callbacks));
+ else
+ dispatcher.CreateFile(url, flags.exclusive(), std::move(callbacks));
+ } else {
+ if (synchronous_type == kSynchronous) {
+ dispatcher.ExistsSync(url, /*is_directory=*/false, std::move(callbacks));
+ } else {
+ dispatcher.Exists(url, /*is_directory=*/false, std::move(callbacks));
+ }
+ }
}
void DOMFileSystemBase::GetDirectory(
@@ -430,57 +411,51 @@ void DOMFileSystemBase::GetDirectory(
EntryCallbacks::OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return;
- }
-
String absolute_path;
if (!PathToAbsolutePath(type_, entry, path, absolute_path)) {
- ReportError(error_callback, FileError::kInvalidModificationErr);
+ ReportError(error_callback, base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create(
success_callback, error_callback, context_, this, absolute_path, true));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
-
- if (flags.createFlag())
- FileSystem()->CreateDirectory(CreateFileSystemURL(absolute_path),
- flags.exclusive(), std::move(callbacks));
- else
- FileSystem()->DirectoryExists(CreateFileSystemURL(absolute_path),
- std::move(callbacks));
+ const KURL& url = CreateFileSystemURL(absolute_path);
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+
+ if (flags.createFlag()) {
+ if (synchronous_type == kSynchronous) {
+ dispatcher.CreateDirectorySync(url, flags.exclusive(),
+ /*recursive=*/false, std::move(callbacks));
+ } else {
+ dispatcher.CreateDirectory(url, flags.exclusive(), /*recursive=*/false,
+ std::move(callbacks));
+ }
+ } else {
+ if (synchronous_type == kSynchronous) {
+ dispatcher.ExistsSync(url, /*is_directory=*/true, std::move(callbacks));
+ } else {
+ dispatcher.Exists(url, /*is_directory=*/true, std::move(callbacks));
+ }
+ }
}
-int DOMFileSystemBase::ReadDirectory(
+void DOMFileSystemBase::ReadDirectory(
DirectoryReaderBase* reader,
const String& path,
EntriesCallbacks::OnDidGetEntriesCallback* success_callback,
ErrorCallbackBase* error_callback,
SynchronousType synchronous_type) {
- if (!FileSystem()) {
- ReportError(error_callback, FileError::kAbortErr);
- return 0;
- }
-
DCHECK(DOMFilePath::IsAbsolute(path));
std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntriesCallbacks::Create(
success_callback, error_callback, context_, reader, path));
- callbacks->SetShouldBlockUntilCompletion(synchronous_type == kSynchronous);
-
- return FileSystem()->ReadDirectory(CreateFileSystemURL(path),
- std::move(callbacks));
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_);
+ const KURL& url = CreateFileSystemURL(path);
+ if (synchronous_type == kSynchronous) {
+ dispatcher.ReadDirectorySync(url, std::move(callbacks));
+ } else {
+ dispatcher.ReadDirectory(url, std::move(callbacks));
+ }
}
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeTemporary,
- mojom::blink::FileSystemType::kTemporary);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypePersistent,
- mojom::blink::FileSystemType::kPersistent);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeExternal,
- mojom::blink::FileSystemType::kExternal);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeIsolated,
- mojom::blink::FileSystemType::kIsolated);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
index 76496faac03..83452e2aa1b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
@@ -42,10 +42,6 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class WebFileSystem;
-} // namespace blink
-
-namespace blink {
class DirectoryReaderBase;
class EntryBase;
@@ -78,12 +74,11 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
virtual void RemovePendingCallbacks() {}
// Overridden by subclasses to handle sync vs async error-handling.
- virtual void ReportError(ErrorCallbackBase*, FileError::ErrorCode) = 0;
+ virtual void ReportError(ErrorCallbackBase*, base::File::Error error) = 0;
const String& name() const { return name_; }
mojom::blink::FileSystemType GetType() const { return type_; }
KURL RootURL() const { return filesystem_root_url_; }
- WebFileSystem* FileSystem() const;
const SecurityOrigin* GetSecurityOrigin() const;
// The clonable flag is used in the structured clone algorithm to test
@@ -150,11 +145,11 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
EntryCallbacks::OnDidGetEntryCallback*,
ErrorCallbackBase*,
SynchronousType = kAsynchronous);
- int ReadDirectory(DirectoryReaderBase*,
- const String& path,
- EntriesCallbacks::OnDidGetEntriesCallback*,
- ErrorCallbackBase*,
- SynchronousType = kAsynchronous);
+ void ReadDirectory(DirectoryReaderBase*,
+ const String& path,
+ EntriesCallbacks::OnDidGetEntriesCallback*,
+ ErrorCallbackBase*,
+ SynchronousType = kAsynchronous);
void Trace(blink::Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
index e560d7ae23b..1d1b6e1008c 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
@@ -33,14 +33,13 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/platform/web_file_system.h"
-#include "third_party/blink/public/platform/web_file_system_callbacks.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/directory_entry_sync.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_path.h"
#include "third_party/blink/renderer/modules/filesystem/file_entry_sync.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer_sync.h"
#include "third_party/blink/renderer/modules/filesystem/sync_callback_helper.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -65,8 +64,8 @@ DOMFileSystemSync::DOMFileSystemSync(ExecutionContext* context,
DOMFileSystemSync::~DOMFileSystemSync() = default;
void DOMFileSystemSync::ReportError(ErrorCallbackBase* error_callback,
- FileError::ErrorCode file_error) {
- error_callback->Invoke(file_error);
+ base::File::Error error) {
+ error_callback->Invoke(error);
}
DirectoryEntrySync* DOMFileSystemSync::root() {
@@ -82,13 +81,13 @@ class CreateFileHelper final : public AsyncFileSystemCallbacks {
static CreateFileResult* Create() { return new CreateFileResult(); }
bool failed_;
- int code_;
+ base::File::Error error_;
Member<File> file_;
void Trace(blink::Visitor* visitor) { visitor->Trace(file_); }
private:
- CreateFileResult() : failed_(false), code_(0) {}
+ CreateFileResult() : failed_(false), error_(base::File::FILE_OK) {}
};
static std::unique_ptr<AsyncFileSystemCallbacks> Create(
@@ -100,9 +99,9 @@ class CreateFileHelper final : public AsyncFileSystemCallbacks {
new CreateFileHelper(result, name, url, type)));
}
- void DidFail(int code) override {
+ void DidFail(base::File::Error error) override {
result_->failed_ = true;
- result_->code_ = code;
+ result_->error_ = error;
}
~CreateFileHelper() override = default;
@@ -120,8 +119,6 @@ class CreateFileHelper final : public AsyncFileSystemCallbacks {
DOMFileSystemBase::CreateFile(metadata, url_, type_, name_);
}
- bool ShouldBlockUntilCompletion() const override { return true; }
-
private:
CreateFileHelper(CreateFileResult* result,
const String& name,
@@ -142,12 +139,12 @@ File* DOMFileSystemSync::CreateFile(const FileEntrySync* file_entry,
KURL file_system_url = CreateFileSystemURL(file_entry);
CreateFileHelper::CreateFileResult* result(
CreateFileHelper::CreateFileResult::Create());
- FileSystem()->CreateSnapshotFileAndReadMetadata(
+ FileSystemDispatcher::From(context_).CreateSnapshotFileSync(
file_system_url, CreateFileHelper::Create(result, file_entry->name(),
file_system_url, GetType()));
if (result->failed_) {
FileError::ThrowDOMException(
- exception_state, static_cast<FileError::ErrorCode>(result->code_),
+ exception_state, result->error_,
"Could not create '" + file_entry->name() + "'.");
return nullptr;
}
@@ -159,7 +156,7 @@ FileWriterSync* DOMFileSystemSync::CreateWriter(
ExceptionState& exception_state) {
DCHECK(file_entry);
- FileWriterSync* file_writer = FileWriterSync::Create();
+ FileWriterSync* file_writer = FileWriterSync::Create(context_);
FileWriterCallbacksSyncHelper* sync_helper =
FileWriterCallbacksSyncHelper::Create();
@@ -167,10 +164,9 @@ FileWriterSync* DOMFileSystemSync::CreateWriter(
FileWriterCallbacks::Create(file_writer,
sync_helper->GetSuccessCallback(),
sync_helper->GetErrorCallback(), context_);
- callbacks->SetShouldBlockUntilCompletion(true);
- FileSystem()->CreateFileWriter(CreateFileSystemURL(file_entry), file_writer,
- std::move(callbacks));
+ FileSystemDispatcher::From(context_).InitializeFileWriterSync(
+ CreateFileSystemURL(file_entry), std::move(callbacks));
FileWriterBase* success = sync_helper->GetResultOrThrow(exception_state);
return success ? file_writer : nullptr;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
index b4d4f863f78..228b3e0b211 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h
@@ -57,7 +57,7 @@ class DOMFileSystemSync final : public DOMFileSystemBase {
~DOMFileSystemSync() override;
- void ReportError(ErrorCallbackBase*, FileError::ErrorCode) override;
+ void ReportError(ErrorCallbackBase*, base::File::Error error) override;
DirectoryEntrySync* root();
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
index cf8d2aa0ef2..52b1e87c04d 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/modules/filesystem/dom_window_file_system.h"
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -32,8 +34,11 @@
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/modules/filesystem/choose_file_system_entries_options.h"
+#include "third_party/blink/renderer/modules/filesystem/directory_entry.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/modules/filesystem/local_file_system.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -60,7 +65,7 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
if (!document->GetSecurityOrigin()->CanAccessFileSystem()) {
DOMFileSystem::ReportError(document,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kSecurityErr);
+ base::File::FILE_ERROR_SECURITY);
return;
} else if (document->GetSecurityOrigin()->IsLocal()) {
UseCounter::Count(document, WebFeature::kFileAccessedFileSystem);
@@ -71,7 +76,7 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
DOMFileSystem::ReportError(document,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kInvalidModificationErr);
+ base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
@@ -81,7 +86,8 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
FileSystemCallbacks::OnDidOpenFileSystemV8Impl::Create(
success_callback),
ScriptErrorCallback::Wrap(error_callback), document,
- file_system_type));
+ file_system_type),
+ LocalFileSystem::kAsynchronous);
}
void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
@@ -102,7 +108,7 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
!security_origin->CanRequest(completed_url)) {
DOMFileSystem::ReportError(document,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kSecurityErr);
+ base::File::FILE_ERROR_SECURITY);
return;
} else if (document->GetSecurityOrigin()->IsLocal()) {
UseCounter::Count(document, WebFeature::kFileAccessedFileSystem);
@@ -111,7 +117,7 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
if (!completed_url.IsValid()) {
DOMFileSystem::ReportError(document,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kEncodingErr);
+ base::File::FILE_ERROR_INVALID_URL);
return;
}
@@ -119,7 +125,8 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
document, completed_url,
ResolveURICallbacks::Create(
ResolveURICallbacks::OnDidGetEntryV8Impl::Create(success_callback),
- ScriptErrorCallback::Wrap(error_callback), document));
+ ScriptErrorCallback::Wrap(error_callback), document),
+ LocalFileSystem::kAsynchronous);
}
static_assert(
@@ -131,9 +138,69 @@ static_assert(
static_cast<int>(mojom::blink::FileSystemType::kPersistent),
"DOMWindowFileSystem::kPersistent should match FileSystemTypePersistent");
+namespace {
+
+mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input,
+ bool multiple) {
+ if (input == "openFile") {
+ return multiple
+ ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles
+ : mojom::blink::ChooseFileSystemEntryType::kOpenFile;
+ }
+ if (input == "saveFile")
+ return mojom::blink::ChooseFileSystemEntryType::kSaveFile;
+ if (input == "openDirectory")
+ return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory;
+ NOTREACHED();
+ return mojom::blink::ChooseFileSystemEntryType::kOpenFile;
+}
+
+Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts(
+ const HeapVector<ChooseFileSystemEntriesOptionsAccepts>& accepts) {
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result;
+ result.ReserveInitialCapacity(accepts.size());
+ for (const auto& a : accepts) {
+ result.emplace_back(
+ blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New(
+ a.hasDescription() ? a.description() : g_empty_string,
+ a.hasMimeTypes() ? a.mimeTypes() : Vector<String>(),
+ a.hasExtensions() ? a.extensions() : Vector<String>()));
+ }
+ return result;
+}
+
+ScriptPromise CreateFileHandle(ScriptState* script_state,
+ const mojom::blink::FileSystemEntryPtr& entry,
+ bool is_directory) {
+ auto* new_resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = new_resolver->Promise();
+ auto* fs = DOMFileSystem::CreateIsolatedFileSystem(
+ ExecutionContext::From(script_state), entry->file_system_id);
+ // TODO(mek): Try to create handle directly rather than having to do more
+ // IPCs to get the actual entries.
+ if (is_directory) {
+ fs->GetDirectory(fs->root(), entry->base_name, FileSystemFlags(),
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver),
+ new PromiseErrorCallback(new_resolver));
+ } else {
+ fs->GetFile(fs->root(), entry->base_name, FileSystemFlags(),
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver),
+ new PromiseErrorCallback(new_resolver));
+ }
+ return result;
+}
+
+} // namespace
+
ScriptPromise DOMWindowFileSystem::chooseFileSystemEntries(
ScriptState* script_state,
- LocalDOMWindow& window) {
+ LocalDOMWindow& window,
+ const ChooseFileSystemEntriesOptions& options) {
+ if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kAbortError));
+ }
+
if (!window.IsCurrentlyDisplayedInFrame()) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kAbortError));
@@ -145,7 +212,7 @@ ScriptPromise DOMWindowFileSystem::chooseFileSystemEntries(
script_state, DOMException::Create(DOMExceptionCode::kAbortError));
}
- if (!Frame::HasTransientUserActivation(window.GetFrame())) {
+ if (!LocalFrame::HasTransientUserActivation(window.GetFrame())) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
@@ -153,9 +220,44 @@ ScriptPromise DOMWindowFileSystem::chooseFileSystemEntries(
"Must be handling a user gesture to show a file picker."));
}
+ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ if (options.hasAccepts())
+ accepts = ConvertAccepts(options.accepts());
+
auto* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise result = resolver->Promise();
- LocalFileSystem::From(*document)->ChooseEntry(resolver);
+ FileSystemDispatcher::From(document).GetFileSystemManager().ChooseEntry(
+ ConvertChooserType(options.type(), options.multiple()),
+ std::move(accepts), !options.excludeAcceptAllOption(),
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver,
+ const ChooseFileSystemEntriesOptions& options,
+ base::File::Error result,
+ Vector<mojom::blink::FileSystemEntryPtr> entries) {
+ if (result != base::File::FILE_OK) {
+ resolver->Reject(FileError::CreateDOMException(result));
+ return;
+ }
+ bool is_directory = options.type() == "openDirectory";
+ ScriptState* script_state = resolver->GetScriptState();
+ ScriptState::Scope scope(script_state);
+ if (options.multiple()) {
+ Vector<ScriptPromise> result;
+ result.ReserveInitialCapacity(entries.size());
+ for (const auto& entry : entries) {
+ result.emplace_back(
+ CreateFileHandle(script_state, entry, is_directory));
+ }
+ resolver->Resolve(
+ ScriptPromise::All(script_state, result).GetScriptValue());
+ } else {
+ DCHECK_EQ(1u, entries.size());
+ resolver->Resolve(
+ CreateFileHandle(script_state, entries[0], is_directory)
+ .GetScriptValue());
+ }
+ },
+ WrapPersistent(resolver), options));
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
index a12e3beeb9b..8d4264d1f39 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
@@ -32,6 +32,7 @@
namespace blink {
+class ChooseFileSystemEntriesOptions;
class LocalDOMWindow;
class ScriptPromise;
class ScriptState;
@@ -60,7 +61,10 @@ class DOMWindowFileSystem {
kPersistent,
};
- static ScriptPromise chooseFileSystemEntries(ScriptState*, LocalDOMWindow&);
+ static ScriptPromise chooseFileSystemEntries(
+ ScriptState*,
+ LocalDOMWindow&,
+ const ChooseFileSystemEntriesOptions&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
index f991bfb05f4..1fcaa2f115c 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h"
namespace blink {
@@ -23,4 +24,35 @@ ScriptPromise FileSystemBaseHandle::getParent(ScriptState* script_state) {
return result;
}
+ScriptPromise FileSystemBaseHandle::moveTo(ScriptState* script_state,
+ FileSystemDirectoryHandle* parent,
+ const String& name) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->Move(this, parent, name,
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+ScriptPromise FileSystemBaseHandle::copyTo(ScriptState* script_state,
+ FileSystemDirectoryHandle* parent,
+ const String& name) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->Copy(this, parent, name,
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+ScriptPromise FileSystemBaseHandle::remove(ScriptState* script_state) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->Remove(this,
+ new VoidCallbacks::OnDidSucceedPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h
index 991b19dbc71..c1585c93625 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/modules/filesystem/entry_base.h"
namespace blink {
+class FileSystemDirectoryHandle;
class ScriptPromise;
class ScriptState;
@@ -18,6 +19,13 @@ class FileSystemBaseHandle : public EntryBase {
explicit FileSystemBaseHandle(DOMFileSystemBase*, const String& full_path);
ScriptPromise getParent(ScriptState*);
+ ScriptPromise moveTo(ScriptState*,
+ FileSystemDirectoryHandle* parent,
+ const String& name = String());
+ ScriptPromise copyTo(ScriptState*,
+ FileSystemDirectoryHandle* parent,
+ const String& name = String());
+ ScriptPromise remove(ScriptState*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl
index 70d7786e194..20008ad4737 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://wicg.github.io/writable-files/#filesystemhandle
[
RuntimeEnabled=WritableFiles,
NoInterfaceObject
@@ -16,5 +16,10 @@
readonly attribute USVString name;
[CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getParent();
- // TODO(mek): Other methods to move/copy/delete entries.
+
+ [CallWith=ScriptState] Promise<FileSystemBaseHandle> moveTo(
+ FileSystemDirectoryHandle parent, optional USVString name);
+ [CallWith=ScriptState] Promise<FileSystemBaseHandle> copyTo(
+ FileSystemDirectoryHandle parent, optional USVString name);
+ [CallWith=ScriptState] Promise<void> remove();
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
index 139e795f2d0..06bde35238c 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
@@ -33,7 +33,6 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/platform/web_file_writer.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -72,17 +71,15 @@ FileSystemCallbacksBase::~FileSystemCallbacksBase() {
file_system_->RemovePendingCallbacks();
}
-void FileSystemCallbacksBase::DidFail(int code) {
+void FileSystemCallbacksBase::DidFail(base::File::Error error) {
if (error_callback_) {
InvokeOrScheduleCallback(&ErrorCallbackBase::Invoke,
- error_callback_.Release(),
- static_cast<FileError::ErrorCode>(code));
+ error_callback_.Release(), error);
}
}
bool FileSystemCallbacksBase::ShouldScheduleCallback() const {
- return !ShouldBlockUntilCompletion() && execution_context_ &&
- execution_context_->IsContextPaused();
+ return execution_context_ && execution_context_->IsContextPaused();
}
template <typename CallbackMemberFunction,
@@ -122,7 +119,7 @@ void ScriptErrorCallback::Trace(blink::Visitor* visitor) {
visitor->Trace(callback_);
}
-void ScriptErrorCallback::Invoke(FileError::ErrorCode error) {
+void ScriptErrorCallback::Invoke(base::File::Error error) {
callback_->InvokeAndReportException(nullptr,
FileError::CreateDOMException(error));
};
@@ -140,7 +137,7 @@ void PromiseErrorCallback::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
}
-void PromiseErrorCallback::Invoke(FileError::ErrorCode error) {
+void PromiseErrorCallback::Invoke(base::File::Error error) {
resolver_->Reject(FileError::CreateDOMException(error));
}
@@ -265,6 +262,21 @@ void FileSystemCallbacks::OnDidOpenFileSystemV8Impl::OnSuccess(
callback_->InvokeAndReportException(nullptr, file_system);
}
+FileSystemCallbacks::OnDidOpenFileSystemPromiseImpl::
+ OnDidOpenFileSystemPromiseImpl(ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+
+void FileSystemCallbacks::OnDidOpenFileSystemPromiseImpl::Trace(
+ Visitor* visitor) {
+ OnDidOpenFileSystemCallback::Trace(visitor);
+ visitor->Trace(resolver_);
+}
+
+void FileSystemCallbacks::OnDidOpenFileSystemPromiseImpl::OnSuccess(
+ DOMFileSystem* file_system) {
+ resolver_->Resolve(file_system->root()->asFileSystemHandle());
+}
+
std::unique_ptr<AsyncFileSystemCallbacks> FileSystemCallbacks::Create(
OnDidOpenFileSystemCallback* success_callback,
ErrorCallbackBase* error_callback,
@@ -324,7 +336,7 @@ void ResolveURICallbacks::DidResolveURL(const String& name,
String absolute_path;
if (!DOMFileSystemBase::PathToAbsolutePath(type, root, file_path,
absolute_path)) {
- DidFail(FileError::kInvalidModificationErr);
+ DidFail(base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
@@ -408,16 +420,13 @@ FileWriterCallbacks::FileWriterCallbacks(
file_writer_(file_writer),
success_callback_(success_callback) {}
-void FileWriterCallbacks::DidCreateFileWriter(
- std::unique_ptr<WebFileWriter> file_writer,
- long long length) {
- file_writer_->Initialize(std::move(file_writer), length);
-
+void FileWriterCallbacks::DidCreateFileWriter(const KURL& path,
+ long long length) {
if (!success_callback_)
return;
-
+ file_writer_->Initialize(path, length);
InvokeOrScheduleCallback(&OnDidCreateFileWriterCallback::OnSuccess,
- success_callback_.Release(), file_writer_.Release());
+ success_callback_.Release(), file_writer_);
}
// SnapshotFileCallback -------------------------------------------------------
@@ -487,6 +496,19 @@ void VoidCallbacks::OnDidSucceedV8Impl::OnSuccess(
callback_->InvokeAndReportException(nullptr);
}
+VoidCallbacks::OnDidSucceedPromiseImpl::OnDidSucceedPromiseImpl(
+ ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+
+void VoidCallbacks::OnDidSucceedPromiseImpl::Trace(Visitor* visitor) {
+ OnDidSucceedCallback::Trace(visitor);
+ visitor->Trace(resolver_);
+}
+
+void VoidCallbacks::OnDidSucceedPromiseImpl::OnSuccess(ExecutionContext*) {
+ resolver_->Resolve();
+}
+
std::unique_ptr<AsyncFileSystemCallbacks> VoidCallbacks::Create(
OnDidSucceedCallback* success_callback,
ErrorCallbackBase* error_callback,
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
index b14c82c7fab..04ab209a9d8 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
@@ -68,7 +68,7 @@ class ErrorCallbackBase : public GarbageCollectedFinalized<ErrorCallbackBase> {
public:
virtual ~ErrorCallbackBase() {}
virtual void Trace(blink::Visitor* visitor) {}
- virtual void Invoke(FileError::ErrorCode) = 0;
+ virtual void Invoke(base::File::Error error) = 0;
};
class FileSystemCallbacksBase : public AsyncFileSystemCallbacks {
@@ -76,7 +76,7 @@ class FileSystemCallbacksBase : public AsyncFileSystemCallbacks {
~FileSystemCallbacksBase() override;
// For ErrorCallback.
- void DidFail(int code) final;
+ void DidFail(base::File::Error error) final;
// Other callback methods are implemented by each subclass.
@@ -111,7 +111,7 @@ class ScriptErrorCallback final : public ErrorCallbackBase {
~ScriptErrorCallback() override {}
void Trace(blink::Visitor*) override;
- void Invoke(FileError::ErrorCode) override;
+ void Invoke(base::File::Error error) override;
private:
explicit ScriptErrorCallback(V8ErrorCallback*);
@@ -122,7 +122,7 @@ class PromiseErrorCallback final : public ErrorCallbackBase {
public:
explicit PromiseErrorCallback(ScriptPromiseResolver*);
void Trace(Visitor*) override;
- void Invoke(FileError::ErrorCode) override;
+ void Invoke(base::File::Error error) override;
private:
Member<ScriptPromiseResolver> resolver_;
@@ -249,6 +249,16 @@ class FileSystemCallbacks final : public FileSystemCallbacksBase {
Member<V8PersistentCallbackInterface<V8FileSystemCallback>> callback_;
};
+ class OnDidOpenFileSystemPromiseImpl : public OnDidOpenFileSystemCallback {
+ public:
+ explicit OnDidOpenFileSystemPromiseImpl(ScriptPromiseResolver*);
+ void Trace(Visitor*) override;
+ void OnSuccess(DOMFileSystem*) override;
+
+ private:
+ Member<ScriptPromiseResolver> resolver_;
+ };
+
static std::unique_ptr<AsyncFileSystemCallbacks> Create(
OnDidOpenFileSystemCallback*,
ErrorCallbackBase*,
@@ -361,8 +371,7 @@ class FileWriterCallbacks final : public FileSystemCallbacksBase {
OnDidCreateFileWriterCallback*,
ErrorCallbackBase*,
ExecutionContext*);
- void DidCreateFileWriter(std::unique_ptr<WebFileWriter>,
- long long length) override;
+ void DidCreateFileWriter(const KURL& path, long long length) override;
private:
FileWriterCallbacks(FileWriterBase*,
@@ -451,6 +460,16 @@ class VoidCallbacks final : public FileSystemCallbacksBase {
Member<V8PersistentCallbackInterface<V8VoidCallback>> callback_;
};
+ class OnDidSucceedPromiseImpl : public OnDidSucceedCallback {
+ public:
+ OnDidSucceedPromiseImpl(ScriptPromiseResolver*);
+ void Trace(Visitor*) override;
+ void OnSuccess(ExecutionContext*) override;
+
+ private:
+ Member<ScriptPromiseResolver> resolver_;
+ };
+
static std::unique_ptr<AsyncFileSystemCallbacks> Create(OnDidSucceedCallback*,
ErrorCallbackBase*,
ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
index c10c7a481db..4bc2d834eda 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
@@ -7,6 +7,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h"
+#include "third_party/blink/renderer/modules/filesystem/local_file_system.h"
namespace blink {
@@ -15,23 +17,83 @@ FileSystemDirectoryHandle::FileSystemDirectoryHandle(
const String& full_path)
: FileSystemBaseHandle(file_system, full_path) {}
-ScriptPromise FileSystemDirectoryHandle::getFile(ScriptState* script_state,
- const String& name) {
+ScriptPromise FileSystemDirectoryHandle::getFile(
+ ScriptState* script_state,
+ const String& name,
+ const FileSystemGetFileOptions& options) {
+ FileSystemFlags flags;
+ flags.setCreateFlag(options.create());
auto* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise result = resolver->Promise();
- filesystem()->GetFile(this, name, FileSystemFlags(),
+ filesystem()->GetFile(this, name, flags,
new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
new PromiseErrorCallback(resolver));
return result;
}
-ScriptPromise FileSystemDirectoryHandle::getDirectory(ScriptState* script_state,
- const String& name) {
+ScriptPromise FileSystemDirectoryHandle::getDirectory(
+ ScriptState* script_state,
+ const String& name,
+ const FileSystemGetDirectoryOptions& options) {
+ FileSystemFlags flags;
+ flags.setCreateFlag(options.create());
auto* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise result = resolver->Promise();
filesystem()->GetDirectory(
- this, name, FileSystemFlags(),
- new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ this, name, flags, new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+// static
+ScriptPromise FileSystemDirectoryHandle::getSystemDirectory(
+ ScriptState* script_state,
+ const GetSystemDirectoryOptions& options) {
+ auto* context = ExecutionContext::From(script_state);
+
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+
+ LocalFileSystem::From(*context)->RequestFileSystem(
+ context, mojom::blink::FileSystemType::kTemporary, /*size=*/0,
+ FileSystemCallbacks::Create(
+ new FileSystemCallbacks::OnDidOpenFileSystemPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver), context,
+ mojom::blink::FileSystemType::kTemporary),
+ LocalFileSystem::kAsynchronous);
+ return result;
+}
+
+namespace {
+
+void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ V8SetReturnValue(info, info.Data());
+}
+
+} // namespace
+
+ScriptValue FileSystemDirectoryHandle::getEntries(ScriptState* script_state) {
+ auto* iterator = new FileSystemDirectoryIterator(filesystem(), fullPath());
+ auto* isolate = script_state->GetIsolate();
+ auto context = script_state->GetContext();
+ v8::Local<v8::Object> result = v8::Object::New(isolate);
+ if (!result
+ ->Set(context, v8::Symbol::GetAsyncIterator(isolate),
+ v8::Function::New(context, &ReturnDataFunction,
+ ToV8(iterator, script_state))
+ .ToLocalChecked())
+ .ToChecked()) {
+ return ScriptValue();
+ }
+ return ScriptValue(script_state, result);
+}
+
+ScriptPromise FileSystemDirectoryHandle::removeRecursively(
+ ScriptState* script_state) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->RemoveRecursively(
+ this, new VoidCallbacks::OnDidSucceedPromiseImpl(resolver),
new PromiseErrorCallback(resolver));
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h
index cd3fd96fc8c..3dfc770d4b0 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h
@@ -5,7 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_HANDLE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_HANDLE_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_base_handle.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_get_directory_options.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_get_file_options.h"
+#include "third_party/blink/renderer/modules/filesystem/get_system_directory_options.h"
namespace blink {
@@ -16,8 +20,18 @@ class FileSystemDirectoryHandle : public FileSystemBaseHandle {
FileSystemDirectoryHandle(DOMFileSystemBase*, const String& full_path);
bool isDirectory() const override { return true; }
- ScriptPromise getFile(ScriptState*, const String& name);
- ScriptPromise getDirectory(ScriptState*, const String& name);
+ ScriptPromise getFile(ScriptState*,
+ const String& name,
+ const FileSystemGetFileOptions&);
+ ScriptPromise getDirectory(ScriptState*,
+ const String& name,
+ const FileSystemGetDirectoryOptions&);
+ ScriptValue getEntries(ScriptState*);
+ ScriptPromise removeRecursively(ScriptState*);
+
+ static ScriptPromise getSystemDirectory(
+ ScriptState*,
+ const GetSystemDirectoryOptions& options);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl
index 1b13904a04c..5e2309e925a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl
@@ -2,11 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://wicg.github.io/writable-files/#filesystemdirectoryhandle
[
RuntimeEnabled=WritableFiles
] interface FileSystemDirectoryHandle : FileSystemBaseHandle {
- [CallWith=ScriptState] Promise<FileSystemFileHandle> getFile(USVString name);
- [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectory(USVString name);
- // TODO(mek): Other methods such as getEntries etc.
+ [CallWith=ScriptState] Promise<FileSystemFileHandle> getFile(USVString name, optional FileSystemGetFileOptions options);
+ [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectory(USVString name, optional FileSystemGetDirectoryOptions options);
+ [CallWith=ScriptState] object getEntries();
+
+ [CallWith=ScriptState] Promise<void> removeRecursively();
+
+ [CallWith=ScriptState]
+ static Promise<FileSystemDirectoryHandle> getSystemDirectory(GetSystemDirectoryOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc
new file mode 100644
index 00000000000..d7fa8b6cebe
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.cc
@@ -0,0 +1,110 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/fileapi/file_error.h"
+#include "third_party/blink/renderer/modules/filesystem/entry.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_base_handle.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_directory_iterator_entry.h"
+
+namespace blink {
+
+class FileSystemDirectoryIterator::EntriesCallbackHelper
+ : public EntriesCallbacks::OnDidGetEntriesCallback {
+ public:
+ explicit EntriesCallbackHelper(FileSystemDirectoryIterator* reader)
+ : reader_(reader) {}
+
+ void Trace(Visitor* visitor) override {
+ EntriesCallbacks::OnDidGetEntriesCallback::Trace(visitor);
+ visitor->Trace(reader_);
+ }
+
+ void OnSuccess(EntryHeapVector* entries) override {
+ reader_->AddEntries(*entries);
+ }
+
+ private:
+ // TODO(https://crbug.com/350285): This Member keeps the reader alive until
+ // all of the readDirectory results are received.
+ Member<FileSystemDirectoryIterator> reader_;
+};
+
+class FileSystemDirectoryIterator::ErrorCallbackHelper final
+ : public ErrorCallbackBase {
+ public:
+ explicit ErrorCallbackHelper(FileSystemDirectoryIterator* reader)
+ : reader_(reader) {}
+
+ void Invoke(base::File::Error error) override { reader_->OnError(error); }
+
+ void Trace(Visitor* visitor) override {
+ ErrorCallbackBase::Trace(visitor);
+ visitor->Trace(reader_);
+ }
+
+ private:
+ Member<FileSystemDirectoryIterator> reader_;
+};
+
+FileSystemDirectoryIterator::FileSystemDirectoryIterator(
+ DOMFileSystemBase* file_system,
+ const String& full_path)
+ : DirectoryReaderBase(file_system, full_path) {
+ Filesystem()->ReadDirectory(this, full_path_, new EntriesCallbackHelper(this),
+ new ErrorCallbackHelper(this));
+}
+
+ScriptPromise FileSystemDirectoryIterator::next(ScriptState* script_state) {
+ if (error_ != base::File::FILE_OK) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, FileError::CreateDOMException(error_));
+ }
+
+ if (!entries_.IsEmpty()) {
+ FileSystemDirectoryIteratorEntry result;
+ result.setValue(entries_.TakeFirst()->asFileSystemHandle());
+ return ScriptPromise::Cast(script_state, ToV8(result, script_state));
+ }
+
+ if (has_more_entries_) {
+ DCHECK(!pending_next_);
+ pending_next_ = ScriptPromiseResolver::Create(script_state);
+ return pending_next_->Promise();
+ }
+
+ FileSystemDirectoryIteratorEntry result;
+ result.setDone(true);
+ return ScriptPromise::Cast(script_state, ToV8(result, script_state));
+}
+
+void FileSystemDirectoryIterator::Trace(Visitor* visitor) {
+ DirectoryReaderBase::Trace(visitor);
+ visitor->Trace(entries_);
+ visitor->Trace(pending_next_);
+}
+
+void FileSystemDirectoryIterator::AddEntries(const EntryHeapVector& entries) {
+ for (const auto& e : entries)
+ entries_.emplace_back(e);
+ if (pending_next_) {
+ ScriptState::Scope scope(pending_next_->GetScriptState());
+ pending_next_->Resolve(
+ next(pending_next_->GetScriptState()).GetScriptValue());
+ pending_next_ = nullptr;
+ }
+}
+
+void FileSystemDirectoryIterator::OnError(base::File::Error error) {
+ error_ = error;
+ if (pending_next_) {
+ pending_next_->Reject(FileError::CreateDOMException(error));
+ pending_next_ = nullptr;
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h
new file mode 100644
index 00000000000..2f851333a2a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.h
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_ITERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_ITERATOR_H_
+
+#include "base/files/file.h"
+#include "third_party/blink/renderer/modules/filesystem/directory_reader_base.h"
+#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
+
+namespace blink {
+class ScriptPromise;
+class ScriptPromiseResolver;
+class ScriptState;
+
+class FileSystemDirectoryIterator : public DirectoryReaderBase {
+ DEFINE_WRAPPERTYPEINFO();
+ public:
+ FileSystemDirectoryIterator(DOMFileSystemBase*, const String& full_path);
+
+ ScriptPromise next(ScriptState*);
+ // TODO(mek): This return method should cancel the backend directory iteration
+ // operation, to avoid doing useless work.
+ void IteratorReturn() {}
+
+ void Trace(Visitor*) override;
+
+ private:
+ class EntriesCallbackHelper;
+ class ErrorCallbackHelper;
+ void AddEntries(const EntryHeapVector& entries);
+ void OnError(base::File::Error);
+
+ base::File::Error error_ = base::File::FILE_OK;
+ HeapDeque<Member<Entry>> entries_;
+ Member<ScriptPromiseResolver> pending_next_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_ITERATOR_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.idl
new file mode 100644
index 00000000000..bb376bb9220
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator.idl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Async iterator returned by FileSystemDirectoryHandle.getEntries().
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-asynciterator-interface
+[
+ NoInterfaceObject,
+ RuntimeEnabled=WritableFiles
+] interface FileSystemDirectoryIterator {
+ [CallWith=ScriptState] Promise next();
+ [ImplementedAs=IteratorReturn] void return();
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator_entry.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator_entry.idl
new file mode 100644
index 00000000000..3e37520931f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_iterator_entry.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// Used by FileSystemDirectoryIterator to represents results of next() calls.
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-iteratorresult-interface
+dictionary FileSystemDirectoryIteratorEntry {
+ FileSystemBaseHandle value;
+ boolean done = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
new file mode 100644
index 00000000000..a910df063c9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
@@ -0,0 +1,585 @@
+// 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 "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
+
+#include "build/build_config.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class FileSystemDispatcher::WriteListener
+ : public mojom::blink::FileSystemOperationListener {
+ public:
+ WriteListener(const WriteCallback& success_callback,
+ StatusCallback error_callback)
+ : error_callback_(std::move(error_callback)),
+ write_callback_(success_callback) {}
+
+ void ResultsRetrieved(
+ Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
+ bool has_more) override {
+ NOTREACHED();
+ }
+
+ void ErrorOccurred(base::File::Error error_code) override {
+ std::move(error_callback_).Run(error_code);
+ }
+
+ void DidWrite(int64_t byte_count, bool complete) override {
+ write_callback_.Run(byte_count, complete);
+ }
+
+ private:
+ StatusCallback error_callback_;
+ WriteCallback write_callback_;
+};
+
+class FileSystemDispatcher::ReadDirectoryListener
+ : public mojom::blink::FileSystemOperationListener {
+ public:
+ explicit ReadDirectoryListener(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks)
+ : callbacks_(std::move(callbacks)) {}
+
+ void ResultsRetrieved(
+ Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
+ bool has_more) override {
+ for (const auto& entry : entries) {
+ callbacks_->DidReadDirectoryEntry(
+ FilePathToWebString(entry->name),
+ entry->type == filesystem::mojom::blink::FsFileType::DIRECTORY);
+ }
+ callbacks_->DidReadDirectoryEntries(has_more);
+ }
+
+ void ErrorOccurred(base::File::Error error_code) override {
+ callbacks_->DidFail(error_code);
+ }
+
+ void DidWrite(int64_t byte_count, bool complete) override { NOTREACHED(); }
+
+ private:
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks_;
+};
+
+FileSystemDispatcher::FileSystemDispatcher(ExecutionContext& context)
+ : Supplement<ExecutionContext>(context), next_operation_id_(1) {}
+
+// static
+const char FileSystemDispatcher::kSupplementName[] = "FileSystemDispatcher";
+
+// static
+FileSystemDispatcher& FileSystemDispatcher::From(ExecutionContext* context) {
+ DCHECK(context);
+ FileSystemDispatcher* dispatcher =
+ Supplement<ExecutionContext>::From<FileSystemDispatcher>(context);
+ if (!dispatcher) {
+ dispatcher = new FileSystemDispatcher(*context);
+ Supplement<ExecutionContext>::ProvideTo(*context, dispatcher);
+ }
+ return *dispatcher;
+}
+
+FileSystemDispatcher::~FileSystemDispatcher() = default;
+
+mojom::blink::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() {
+ if (!file_system_manager_ptr_) {
+ mojom::blink::FileSystemManagerRequest request =
+ mojo::MakeRequest(&file_system_manager_ptr_);
+ // Document::GetInterfaceProvider() can return null if the frame is
+ // detached.
+ if (GetSupplementable()->GetInterfaceProvider()) {
+ GetSupplementable()->GetInterfaceProvider()->GetInterface(
+ std::move(request));
+ }
+ }
+ DCHECK(file_system_manager_ptr_);
+ return *file_system_manager_ptr_;
+}
+
+void FileSystemDispatcher::OpenFileSystem(
+ const KURL& origin_url,
+ mojom::blink::FileSystemType type,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Open(
+ origin_url, type,
+ WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem,
+ WrapWeakPersistent(this), std::move(callbacks)));
+}
+
+void FileSystemDispatcher::OpenFileSystemSync(
+ const KURL& origin_url,
+ mojom::blink::FileSystemType type,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ String name;
+ KURL root_url;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Open(origin_url, type, &name, &root_url, &error_code);
+ DidOpenFileSystem(std::move(callbacks), std::move(name), root_url,
+ error_code);
+}
+
+void FileSystemDispatcher::ResolveURL(
+ const KURL& filesystem_url,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().ResolveURL(
+ filesystem_url,
+ WTF::Bind(&FileSystemDispatcher::DidResolveURL, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::ResolveURLSync(
+ const KURL& filesystem_url,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ mojom::blink::FileSystemInfoPtr info;
+ base::FilePath file_path;
+ bool is_directory;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().ResolveURL(filesystem_url, &info, &file_path,
+ &is_directory, &error_code);
+ DidResolveURL(std::move(callbacks), std::move(info), std::move(file_path),
+ is_directory, error_code);
+}
+
+void FileSystemDispatcher::Move(
+ const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Move(
+ src_path, dest_path,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::MoveSync(
+ const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Move(src_path, dest_path, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::Copy(
+ const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Copy(
+ src_path, dest_path,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::CopySync(
+ const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Copy(src_path, dest_path, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::Remove(
+ const KURL& path,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Remove(
+ path, recursive,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::RemoveSync(
+ const KURL& path,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Remove(path, recursive, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::ReadMetadata(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().ReadMetadata(
+ path, WTF::Bind(&FileSystemDispatcher::DidReadMetadata,
+ WrapWeakPersistent(this), std::move(callbacks)));
+}
+
+void FileSystemDispatcher::ReadMetadataSync(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Info file_info;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().ReadMetadata(path, &file_info, &error_code);
+ DidReadMetadata(std::move(callbacks), std::move(file_info), error_code);
+}
+
+void FileSystemDispatcher::CreateFile(
+ const KURL& path,
+ bool exclusive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Create(
+ path, exclusive, /*is_directory=*/false, /*is_recursive=*/false,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::CreateFileSync(
+ const KURL& path,
+ bool exclusive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Create(path, exclusive, /*is_directory=*/false,
+ /*is_recursive=*/false, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::CreateDirectory(
+ const KURL& path,
+ bool exclusive,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Create(
+ path, exclusive, /*is_directory=*/true, recursive,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::CreateDirectorySync(
+ const KURL& path,
+ bool exclusive,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Create(path, exclusive, /*is_directory=*/true,
+ recursive, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::Exists(
+ const KURL& path,
+ bool is_directory,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().Exists(
+ path, is_directory,
+ WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
+ std::move(callbacks)));
+}
+
+void FileSystemDispatcher::ExistsSync(
+ const KURL& path,
+ bool is_directory,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().Exists(path, is_directory, &error_code);
+ DidFinish(std::move(callbacks), error_code);
+}
+
+void FileSystemDispatcher::ReadDirectory(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ mojom::blink::FileSystemOperationListenerPtr ptr;
+ mojom::blink::FileSystemOperationListenerRequest request =
+ mojo::MakeRequest(&ptr);
+ op_listeners_.AddBinding(
+ std::make_unique<ReadDirectoryListener>(std::move(callbacks)),
+ std::move(request));
+ GetFileSystemManager().ReadDirectory(path, std::move(ptr));
+}
+
+void FileSystemDispatcher::ReadDirectorySync(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries;
+ base::File::Error result = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().ReadDirectorySync(path, &entries, &result);
+ if (result == base::File::FILE_OK) {
+ DidReadDirectory(std::move(callbacks), std::move(entries),
+ std::move(result));
+ }
+}
+
+void FileSystemDispatcher::InitializeFileWriter(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().ReadMetadata(
+ path, WTF::Bind(&FileSystemDispatcher::InitializeFileWriterCallback,
+ WrapWeakPersistent(this), path, std::move(callbacks)));
+}
+
+void FileSystemDispatcher::InitializeFileWriterSync(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Info file_info;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().ReadMetadata(path, &file_info, &error_code);
+ InitializeFileWriterCallback(path, std::move(callbacks), file_info,
+ error_code);
+}
+
+void FileSystemDispatcher::Truncate(const KURL& path,
+ int64_t offset,
+ int* request_id_out,
+ StatusCallback callback) {
+ mojom::blink::FileSystemCancellableOperationPtr op_ptr;
+ mojom::blink::FileSystemCancellableOperationRequest op_request =
+ mojo::MakeRequest(&op_ptr);
+ int operation_id = next_operation_id_++;
+ op_ptr.set_connection_error_handler(
+ WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr,
+ WrapWeakPersistent(this), operation_id));
+ cancellable_operations_.insert(operation_id, std::move(op_ptr));
+ GetFileSystemManager().Truncate(
+ path, offset, std::move(op_request),
+ WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this),
+ operation_id, std::move(callback)));
+
+ if (request_id_out)
+ *request_id_out = operation_id;
+}
+
+void FileSystemDispatcher::TruncateSync(const KURL& path,
+ int64_t offset,
+ StatusCallback callback) {
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().TruncateSync(path, offset, &error_code);
+ std::move(callback).Run(error_code);
+}
+
+void FileSystemDispatcher::Write(const KURL& path,
+ const String& blob_id,
+ int64_t offset,
+ int* request_id_out,
+ const WriteCallback& success_callback,
+ StatusCallback error_callback) {
+ mojom::blink::FileSystemCancellableOperationPtr op_ptr;
+ mojom::blink::FileSystemCancellableOperationRequest op_request =
+ mojo::MakeRequest(&op_ptr);
+ int operation_id = next_operation_id_++;
+ op_ptr.set_connection_error_handler(
+ WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr,
+ WrapWeakPersistent(this), operation_id));
+ cancellable_operations_.insert(operation_id, std::move(op_ptr));
+
+ mojom::blink::FileSystemOperationListenerPtr listener_ptr;
+ mojom::blink::FileSystemOperationListenerRequest request =
+ mojo::MakeRequest(&listener_ptr);
+ op_listeners_.AddBinding(
+ std::make_unique<WriteListener>(
+ WTF::BindRepeating(&FileSystemDispatcher::DidWrite,
+ WrapWeakPersistent(this), success_callback,
+ operation_id),
+ WTF::Bind(&FileSystemDispatcher::WriteErrorCallback,
+ WrapWeakPersistent(this), std::move(error_callback),
+ operation_id)),
+ std::move(request));
+
+ GetFileSystemManager().Write(path, blob_id, offset, std::move(op_request),
+ std::move(listener_ptr));
+
+ if (request_id_out)
+ *request_id_out = operation_id;
+}
+
+void FileSystemDispatcher::WriteSync(const KURL& path,
+ const String& blob_id,
+ int64_t offset,
+ const WriteCallback& success_callback,
+ StatusCallback error_callback) {
+ int64_t byte_count;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ GetFileSystemManager().WriteSync(path, blob_id, offset, &byte_count,
+ &error_code);
+ if (error_code == base::File::FILE_OK)
+ std::move(success_callback).Run(byte_count, /*complete=*/true);
+ else
+ std::move(error_callback).Run(error_code);
+}
+
+void FileSystemDispatcher::Cancel(int request_id_to_cancel,
+ StatusCallback callback) {
+ if (cancellable_operations_.find(request_id_to_cancel) ==
+ cancellable_operations_.end()) {
+ std::move(callback).Run(base::File::FILE_ERROR_INVALID_OPERATION);
+ return;
+ }
+ cancellable_operations_.find(request_id_to_cancel)
+ ->value->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel,
+ WrapWeakPersistent(this), std::move(callback),
+ request_id_to_cancel));
+}
+
+void FileSystemDispatcher::CreateSnapshotFile(
+ const KURL& file_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ GetFileSystemManager().CreateSnapshotFile(
+ file_path, WTF::Bind(&FileSystemDispatcher::DidCreateSnapshotFile,
+ WrapWeakPersistent(this), std::move(callbacks)));
+}
+
+void FileSystemDispatcher::CreateSnapshotFileSync(
+ const KURL& file_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ base::File::Info file_info;
+ base::FilePath platform_path;
+ base::File::Error error_code = base::File::FILE_ERROR_FAILED;
+ mojom::blink::ReceivedSnapshotListenerPtr listener;
+ GetFileSystemManager().CreateSnapshotFile(
+ file_path, &file_info, &platform_path, &error_code, &listener);
+ DidCreateSnapshotFile(std::move(callbacks), std::move(file_info),
+ std::move(platform_path), error_code,
+ std::move(listener));
+}
+
+void FileSystemDispatcher::DidOpenFileSystem(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const String& name,
+ const KURL& root,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK) {
+ callbacks->DidOpenFileSystem(name, root);
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::DidResolveURL(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ mojom::blink::FileSystemInfoPtr info,
+ const base::FilePath& file_path,
+ bool is_directory,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK) {
+ DCHECK(info->root_url.IsValid());
+ callbacks->DidResolveURL(info->name, info->root_url, info->mount_type,
+ FilePathToWebString(file_path), is_directory);
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::DidFinish(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK)
+ callbacks->DidSucceed();
+ else
+ callbacks->DidFail(error_code);
+}
+
+void FileSystemDispatcher::DidReadMetadata(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK) {
+ callbacks->DidReadMetadata(FileMetadata::From(file_info));
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::DidReadDirectory(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK) {
+ for (const auto& entry : entries) {
+ callbacks->DidReadDirectoryEntry(
+ FilePathToWebString(entry->name),
+ entry->type == filesystem::mojom::blink::FsFileType::DIRECTORY);
+ }
+ callbacks->DidReadDirectoryEntries(false);
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::InitializeFileWriterCallback(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ base::File::Error error_code) {
+ if (error_code == base::File::Error::FILE_OK) {
+ if (file_info.is_directory || file_info.size < 0) {
+ callbacks->DidFail(base::File::FILE_ERROR_FAILED);
+ return;
+ }
+ callbacks->DidCreateFileWriter(path, file_info.size);
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::DidTruncate(int operation_id,
+ StatusCallback callback,
+ base::File::Error error_code) {
+ if (error_code != base::File::FILE_ERROR_ABORT)
+ RemoveOperationPtr(operation_id);
+ std::move(callback).Run(error_code);
+}
+
+void FileSystemDispatcher::DidWrite(const WriteCallback& callback,
+ int operation_id,
+ int64_t bytes,
+ bool complete) {
+ callback.Run(bytes, complete);
+ if (complete)
+ RemoveOperationPtr(operation_id);
+}
+
+void FileSystemDispatcher::WriteErrorCallback(StatusCallback callback,
+ int operation_id,
+ base::File::Error error) {
+ std::move(callback).Run(error);
+ if (error != base::File::FILE_ERROR_ABORT)
+ RemoveOperationPtr(operation_id);
+}
+
+void FileSystemDispatcher::DidCancel(StatusCallback callback,
+ int cancelled_operation_id,
+ base::File::Error error_code) {
+ if (error_code == base::File::FILE_OK)
+ RemoveOperationPtr(cancelled_operation_id);
+ std::move(callback).Run(error_code);
+}
+
+void FileSystemDispatcher::DidCreateSnapshotFile(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ const base::FilePath& platform_path,
+ base::File::Error error_code,
+ mojom::blink::ReceivedSnapshotListenerPtr listener) {
+ if (error_code == base::File::FILE_OK) {
+ FileMetadata file_metadata = FileMetadata::From(file_info);
+ file_metadata.platform_path = FilePathToWebString(platform_path);
+
+ std::unique_ptr<BlobData> blob_data = BlobData::Create();
+ blob_data->AppendFile(file_metadata.platform_path, 0, file_metadata.length,
+ InvalidFileTime());
+ scoped_refptr<BlobDataHandle> snapshot_blob =
+ BlobDataHandle::Create(std::move(blob_data), file_metadata.length);
+
+ callbacks->DidCreateSnapshotFile(file_metadata, snapshot_blob);
+
+ if (listener)
+ listener->DidReceiveSnapshotFile();
+ } else {
+ callbacks->DidFail(error_code);
+ }
+}
+
+void FileSystemDispatcher::RemoveOperationPtr(int operation_id) {
+ DCHECK(cancellable_operations_.find(operation_id) !=
+ cancellable_operations_.end());
+ cancellable_operations_.erase(operation_id);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
new file mode 100644
index 00000000000..ec5f5e8c77b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
@@ -0,0 +1,203 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DISPATCHER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DISPATCHER_H_
+
+#include "mojo/public/cpp/bindings/strong_binding_set.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
+#include "third_party/blink/public/platform/web_callbacks.h"
+#include "third_party/blink/renderer/platform/async_file_system_callbacks.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace WTF {
+class String;
+}
+
+namespace blink {
+
+class KURL;
+class ExecutionContext;
+
+// Sends messages via mojo to the blink::mojom::FileSystemManager service
+// running in the browser process. It is owned by ExecutionContext, and
+// instances are created lazily by calling FileSystemDispatcher::From().
+class FileSystemDispatcher
+ : public GarbageCollectedFinalized<FileSystemDispatcher>,
+ public Supplement<ExecutionContext> {
+ USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher);
+
+ public:
+ using StatusCallback = base::OnceCallback<void(base::File::Error error)>;
+ using WriteCallback =
+ base::RepeatingCallback<void(int64_t bytes, bool complete)>;
+
+ static const char kSupplementName[];
+
+ static FileSystemDispatcher& From(ExecutionContext* context);
+ virtual ~FileSystemDispatcher();
+
+ mojom::blink::FileSystemManager& GetFileSystemManager();
+
+ void OpenFileSystem(const KURL& url,
+ mojom::blink::FileSystemType type,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void OpenFileSystemSync(const KURL& url,
+ mojom::blink::FileSystemType type,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void ResolveURL(const KURL& filesystem_url,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void ResolveURLSync(const KURL& filesystem_url,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void Move(const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void MoveSync(const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void Copy(const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void CopySync(const KURL& src_path,
+ const KURL& dest_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void Remove(const KURL& path,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void RemoveSync(const KURL& path,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void ReadMetadata(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void ReadMetadataSync(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void CreateFile(const KURL& path,
+ bool exclusive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void CreateFileSync(const KURL& path,
+ bool exclusive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void CreateDirectory(const KURL& path,
+ bool exclusive,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void CreateDirectorySync(const KURL& path,
+ bool exclusive,
+ bool recursive,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void Exists(const KURL& path,
+ bool for_directory,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void ExistsSync(const KURL& path,
+ bool for_directory,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void ReadDirectory(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void ReadDirectorySync(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ void InitializeFileWriter(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks>);
+ void InitializeFileWriterSync(const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks>);
+
+ void Truncate(const KURL& path,
+ int64_t offset,
+ int* request_id_out,
+ StatusCallback callback);
+ void TruncateSync(const KURL& path, int64_t offset, StatusCallback callback);
+
+ void Write(const KURL& path,
+ const String& blob_id,
+ int64_t offset,
+ int* request_id_out,
+ const WriteCallback& success_callback,
+ StatusCallback error_callback);
+ void WriteSync(const KURL& path,
+ const String& blob_id,
+ int64_t offset,
+ const WriteCallback& success_callback,
+ StatusCallback error_callback);
+
+ void Cancel(int request_id_to_cancel, StatusCallback callback);
+
+ void CreateSnapshotFile(const KURL& file_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+ void CreateSnapshotFileSync(
+ const KURL& file_path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks);
+
+ private:
+ class WriteListener;
+ class ReadDirectoryListener;
+
+ explicit FileSystemDispatcher(ExecutionContext& context);
+
+ void DidOpenFileSystem(std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const String& name,
+ const KURL& root,
+ base::File::Error error_code);
+ void DidResolveURL(std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ mojom::blink::FileSystemInfoPtr info,
+ const base::FilePath& file_path,
+ bool is_directory,
+ base::File::Error error_code);
+ void DidFinish(std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ base::File::Error error_code);
+ void DidReadMetadata(std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ base::File::Error error);
+ void DidReadDirectory(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
+ base::File::Error error_code);
+ void InitializeFileWriterCallback(
+ const KURL& path,
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ base::File::Error error);
+ void DidTruncate(int operation_id,
+ StatusCallback callback,
+ base::File::Error error_code);
+ void DidWrite(const WriteCallback& callback,
+ int operation_id,
+ int64_t bytes,
+ bool complete);
+ void WriteErrorCallback(StatusCallback callback,
+ int operation_id,
+ base::File::Error error);
+ void DidCancel(StatusCallback callback,
+ int cancelled_operation_id,
+ base::File::Error error_code);
+ void DidCreateSnapshotFile(
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ const base::File::Info& file_info,
+ const base::FilePath& platform_path,
+ base::File::Error error_code,
+ mojom::blink::ReceivedSnapshotListenerPtr listener);
+
+ void RemoveOperationPtr(int operation_id);
+
+ mojom::blink::FileSystemManagerPtr file_system_manager_ptr_;
+ using OperationsMap =
+ HashMap<int, mojom::blink::FileSystemCancellableOperationPtr>;
+ OperationsMap cancellable_operations_;
+ int next_operation_id_;
+ mojo::StrongBindingSet<mojom::blink::FileSystemOperationListener>
+ op_listeners_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DISPATCHER_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
index 91deae419cf..9bf62daa4fc 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -5,38 +5,19 @@
#include "third_party/blink/renderer/modules/filesystem/file_system_file_handle.h"
#include "third_party/blink/public/mojom/filesystem/file_writer.mojom-blink.h"
-#include "third_party/blink/public/platform/web_file_system.h"
+#include "third_party/blink/public/platform/web_callbacks.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_writer.h"
namespace blink {
namespace {
-class CreateWriterCallbacks
- : public WebCallbacks<mojo::ScopedMessagePipeHandle, base::File::Error> {
- public:
- explicit CreateWriterCallbacks(ScriptPromiseResolver* resolver)
- : resolver_(resolver) {}
-
- void OnSuccess(mojo::ScopedMessagePipeHandle handle) override {
- mojom::blink::FileWriterPtr mojo_writer(mojom::blink::FileWriterPtrInfo(
- std::move(handle), mojom::blink::FileWriter::Version_));
- resolver_->Resolve(new FileSystemWriter(std::move(mojo_writer)));
- }
-
- void OnError(base::File::Error error) override {
- resolver_->Reject(FileError::CreateDOMException(error));
- }
-
- private:
- Persistent<ScriptPromiseResolver> resolver_;
-};
-
class OnDidCreateSnapshotFilePromise
: public SnapshotFileCallback::OnDidCreateSnapshotFileCallback {
public:
@@ -59,34 +40,36 @@ FileSystemFileHandle::FileSystemFileHandle(DOMFileSystemBase* file_system,
: FileSystemBaseHandle(file_system, full_path) {}
ScriptPromise FileSystemFileHandle::createWriter(ScriptState* script_state) {
- if (!filesystem()->FileSystem()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, FileError::CreateDOMException(FileError::kAbortErr));
- }
-
auto* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise result = resolver->Promise();
- filesystem()->FileSystem()->CreateFileWriter(
- filesystem()->CreateFileSystemURL(this),
- std::make_unique<CreateWriterCallbacks>(resolver));
+ FileSystemDispatcher::From(ExecutionContext::From(script_state))
+ .GetFileSystemManager()
+ .CreateWriter(
+ filesystem()->CreateFileSystemURL(this),
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver, base::File::Error result,
+ mojom::blink::FileWriterPtr writer) {
+ if (result == base::File::FILE_OK) {
+ resolver->Resolve(new FileSystemWriter(std::move(writer)));
+ } else {
+ resolver->Reject(FileError::CreateDOMException(result));
+ }
+ },
+ WrapPersistent(resolver)));
return result;
}
ScriptPromise FileSystemFileHandle::getFile(ScriptState* script_state) {
- if (!filesystem()->FileSystem()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, FileError::CreateDOMException(FileError::kAbortErr));
- }
-
auto* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise result = resolver->Promise();
KURL file_system_url = filesystem()->CreateFileSystemURL(this);
- filesystem()->FileSystem()->CreateSnapshotFileAndReadMetadata(
- file_system_url,
- SnapshotFileCallback::Create(filesystem(), name(), file_system_url,
- new OnDidCreateSnapshotFilePromise(resolver),
- new PromiseErrorCallback(resolver),
- ExecutionContext::From(script_state)));
+ FileSystemDispatcher::From(ExecutionContext::From(script_state))
+ .CreateSnapshotFile(file_system_url,
+ SnapshotFileCallback::Create(
+ filesystem(), name(), file_system_url,
+ new OnDidCreateSnapshotFilePromise(resolver),
+ new PromiseErrorCallback(resolver),
+ ExecutionContext::From(script_state)));
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl
index 7b554909e65..74f5582f547 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://wicg.github.io/writable-files/#filesystemfilehandle
[
RuntimeEnabled=WritableFiles
] interface FileSystemFileHandle : FileSystemBaseHandle {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_directory_options.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_directory_options.idl
new file mode 100644
index 00000000000..246e8108b53
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_directory_options.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://wicg.github.io/writable-files/#dictdef-filesystemgetdirectoryoptions
+dictionary FileSystemGetDirectoryOptions {
+ boolean create = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_file_options.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_file_options.idl
new file mode 100644
index 00000000000..19c7978f439
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_get_file_options.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://wicg.github.io/writable-files/#dictdef-filesystemgetfileoptions
+dictionary FileSystemGetFileOptions {
+ boolean create = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
index ab254de4e6e..89ec9b3f123 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -5,9 +5,13 @@
#include "third_party/blink/renderer/modules/filesystem/file_system_writer.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h"
+#include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_operations.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -19,7 +23,26 @@ FileSystemWriter::FileSystemWriter(mojom::blink::FileWriterPtr writer)
ScriptPromise FileSystemWriter::write(ScriptState* script_state,
uint64_t position,
- Blob* blob) {
+ ScriptValue data,
+ ExceptionState& exception_state) {
+ v8::Isolate* isolate = script_state->GetIsolate();
+ if (V8Blob::hasInstance(data.V8Value(), isolate)) {
+ Blob* blob = V8Blob::ToImpl(data.V8Value().As<v8::Object>());
+ return WriteBlob(script_state, position, blob);
+ }
+ if (!ReadableStreamOperations::IsReadableStream(script_state, data,
+ exception_state)
+ .value_or(false)) {
+ if (!exception_state.HadException())
+ exception_state.ThrowTypeError("data should be a Blob or ReadableStream");
+ return ScriptPromise();
+ }
+ return WriteStream(script_state, position, data, exception_state);
+}
+
+ScriptPromise FileSystemWriter::WriteBlob(ScriptState* script_state,
+ uint64_t position,
+ Blob* blob) {
if (!writer_ || pending_operation_) {
return ScriptPromise::RejectWithDOMException(
script_state,
@@ -33,6 +56,121 @@ ScriptPromise FileSystemWriter::write(ScriptState* script_state,
return result;
}
+class FileSystemWriter::StreamWriterClient
+ : public GarbageCollectedFinalized<StreamWriterClient>,
+ public FetchDataLoader::Client {
+ USING_GARBAGE_COLLECTED_MIXIN(StreamWriterClient);
+
+ public:
+ explicit StreamWriterClient(FileSystemWriter* writer) : writer_(writer) {}
+
+ void DidFetchDataStartedDataPipe(
+ mojo::ScopedDataPipeConsumerHandle data_pipe) override {
+ data_pipe_ = std::move(data_pipe);
+ }
+
+ mojo::ScopedDataPipeConsumerHandle TakeDataPipe() {
+ DCHECK(data_pipe_);
+ return std::move(data_pipe_);
+ }
+
+ void DidFetchDataLoadedDataPipe() override {
+ // WriteComplete could have been called with an error before we reach this
+ // point, in that case just return.
+ if (did_complete_)
+ return;
+ DCHECK(!did_finish_writing_to_pipe_);
+ DCHECK(writer_->pending_operation_);
+ did_finish_writing_to_pipe_ = true;
+ }
+
+ void DidFetchDataLoadFailed() override {
+ // WriteComplete could have been called with an error before we reach this
+ // point, in that case just return.
+ if (did_complete_)
+ return;
+ DCHECK(writer_->pending_operation_);
+ did_complete_ = true;
+ writer_->pending_operation_->Reject(
+ FileError::CreateDOMException(base::File::FILE_ERROR_FAILED));
+ Reset();
+ }
+
+ void Abort() override {
+ // WriteComplete could have been called with an error before we reach this
+ // point, in that case just return.
+ if (did_complete_)
+ return;
+ DCHECK(writer_->pending_operation_);
+ did_complete_ = true;
+ writer_->pending_operation_->Reject(
+ FileError::CreateDOMException(base::File::FILE_ERROR_ABORT));
+ Reset();
+ }
+
+ void WriteComplete(base::File::Error result, uint64_t bytes_written) {
+ // Early return if we already completed (with an error) before.
+ if (did_complete_)
+ return;
+ DCHECK(writer_->pending_operation_);
+ did_complete_ = true;
+ if (result != base::File::FILE_OK) {
+ writer_->pending_operation_->Reject(
+ FileError::CreateDOMException(result));
+ } else {
+ DCHECK(did_finish_writing_to_pipe_);
+ writer_->pending_operation_->Resolve();
+ }
+ Reset();
+ }
+
+ void Trace(Visitor* visitor) override {
+ Client::Trace(visitor);
+ visitor->Trace(writer_);
+ }
+
+ private:
+ void Reset() {
+ writer_->pending_operation_ = nullptr;
+ writer_->stream_loader_ = nullptr;
+ }
+
+ Member<FileSystemWriter> writer_;
+ mojo::ScopedDataPipeConsumerHandle data_pipe_;
+ bool did_finish_writing_to_pipe_ = false;
+ bool did_complete_ = false;
+};
+
+ScriptPromise FileSystemWriter::WriteStream(ScriptState* script_state,
+ uint64_t position,
+ ScriptValue stream,
+ ExceptionState& exception_state) {
+ if (!writer_ || pending_operation_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(DOMExceptionCode::kInvalidStateError));
+ }
+ DCHECK(!stream_loader_);
+
+ auto reader = ReadableStreamOperations::GetReader(script_state, stream,
+ exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+ auto* consumer = new ReadableStreamBytesConsumer(script_state, reader);
+
+ stream_loader_ = FetchDataLoader::CreateLoaderAsDataPipe(
+ ExecutionContext::From(script_state)
+ ->GetTaskRunner(TaskType::kInternalDefault));
+ pending_operation_ = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ auto* client = new StreamWriterClient(this);
+ stream_loader_->Start(consumer, client);
+ writer_->WriteStream(
+ position, client->TakeDataPipe(),
+ WTF::Bind(&StreamWriterClient::WriteComplete, WrapPersistent(client)));
+ return result;
+}
+
ScriptPromise FileSystemWriter::truncate(ScriptState* script_state,
uint64_t size) {
if (!writer_ || pending_operation_) {
@@ -60,6 +198,7 @@ ScriptPromise FileSystemWriter::close(ScriptState* script_state) {
void FileSystemWriter::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
visitor->Trace(pending_operation_);
+ visitor->Trace(stream_loader_);
}
void FileSystemWriter::WriteComplete(base::File::Error result,
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h
index f00cd9f417f..6fa00725759 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h
@@ -7,13 +7,17 @@
#include "third_party/blink/public/mojom/filesystem/file_writer.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
namespace blink {
class Blob;
+class ExceptionState;
+class FetchDataLoader;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
+class ScriptValue;
class FileSystemWriter final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -21,19 +25,31 @@ class FileSystemWriter final : public ScriptWrappable {
public:
explicit FileSystemWriter(mojom::blink::FileWriterPtr);
- ScriptPromise write(ScriptState*, uint64_t position, Blob*);
+ ScriptPromise write(ScriptState*,
+ uint64_t position,
+ ScriptValue data,
+ ExceptionState&);
ScriptPromise truncate(ScriptState*, uint64_t size);
ScriptPromise close(ScriptState*);
void Trace(Visitor*) override;
private:
+ class StreamWriterClient;
+
+ ScriptPromise WriteBlob(ScriptState*, uint64_t position, Blob*);
+ ScriptPromise WriteStream(ScriptState*,
+ uint64_t position,
+ ScriptValue stream,
+ ExceptionState&);
+
void WriteComplete(base::File::Error result, uint64_t bytes_written);
void TruncateComplete(base::File::Error result);
mojom::blink::FileWriterPtr writer_;
Member<ScriptPromiseResolver> pending_operation_;
+ TraceWrapperMember<FetchDataLoader> stream_loader_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
index c4362be6e59..b1cf94195ac 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+// https://wicg.github.io/writable-files/#filesystemwriter
[
NoInterfaceObject,
RuntimeEnabled=WritableFiles
] interface FileSystemWriter {
- // TODO(mek): Support other types, such as ReadableStream, by using 'any'.
- [CallWith=ScriptState] Promise<void> write(unsigned long long position, Blob data);
+ // TODO(mek): 'any' really is 'Blob or ReadableStream', but that's not
+ // currently supported by our bindings.
+ [CallWith=ScriptState, RaisesException] Promise<void> write(unsigned long long position, any data);
[CallWith=ScriptState] Promise<void> truncate(unsigned long long size);
[CallWith=ScriptState] Promise<void> close();
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
index b8f8bb66861..5ad31e6b662 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -30,11 +30,11 @@
#include "third_party/blink/renderer/modules/filesystem/file_writer.h"
-#include "third_party/blink/public/platform/web_file_writer.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/core/events/progress_event.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -57,11 +57,11 @@ FileWriter::FileWriter(ExecutionContext* context)
truncate_length_(-1),
num_aborts_(0),
recursion_depth_(0),
- last_progress_notification_time_ms_(0) {}
+ last_progress_notification_time_ms_(0),
+ request_id_(0) {}
FileWriter::~FileWriter() {
DCHECK(!recursion_depth_);
- DCHECK(!Writer());
}
const AtomicString& FileWriter::InterfaceName() const {
@@ -81,7 +81,6 @@ void FileWriter::write(Blob* data, ExceptionState& exception_state) {
if (!GetExecutionContext())
return;
DCHECK(data);
- DCHECK(Writer());
DCHECK_EQ(truncate_length_, -1);
if (ready_state_ == kWriting) {
SetError(FileError::kInvalidStateErr, exception_state);
@@ -111,7 +110,6 @@ void FileWriter::write(Blob* data, ExceptionState& exception_state) {
void FileWriter::seek(long long position, ExceptionState& exception_state) {
if (!GetExecutionContext())
return;
- DCHECK(Writer());
if (ready_state_ == kWriting) {
SetError(FileError::kInvalidStateErr, exception_state);
return;
@@ -125,7 +123,6 @@ void FileWriter::seek(long long position, ExceptionState& exception_state) {
void FileWriter::truncate(long long position, ExceptionState& exception_state) {
if (!GetExecutionContext())
return;
- DCHECK(Writer());
DCHECK_EQ(truncate_length_, -1);
if (ready_state_ == kWriting || position < 0) {
SetError(FileError::kInvalidStateErr, exception_state);
@@ -154,16 +151,15 @@ void FileWriter::truncate(long long position, ExceptionState& exception_state) {
void FileWriter::abort(ExceptionState& exception_state) {
if (!GetExecutionContext())
return;
- DCHECK(Writer());
if (ready_state_ != kWriting)
return;
++num_aborts_;
DoOperation(kOperationAbort);
- SignalCompletion(FileError::kAbortErr);
+ SignalCompletion(base::File::FILE_ERROR_ABORT);
}
-void FileWriter::DidWrite(long long bytes, bool complete) {
+void FileWriter::DidWriteImpl(int64_t bytes, bool complete) {
if (operation_in_progress_ == kOperationAbort) {
CompleteAbort();
return;
@@ -183,7 +179,7 @@ void FileWriter::DidWrite(long long bytes, bool complete) {
operation_in_progress_ = kOperationNone;
}
- int num_aborts = num_aborts_;
+ long long num_aborts = num_aborts_;
// We could get an abort in the handler for this event. If we do, it's
// already handled the cleanup and signalCompletion call.
double now = CurrentTimeMS();
@@ -196,11 +192,11 @@ void FileWriter::DidWrite(long long bytes, bool complete) {
if (complete) {
if (num_aborts == num_aborts_)
- SignalCompletion(FileError::kOK);
+ SignalCompletion(base::File::FILE_OK);
}
}
-void FileWriter::DidTruncate() {
+void FileWriter::DidTruncateImpl() {
if (operation_in_progress_ == kOperationAbort) {
CompleteAbort();
return;
@@ -211,12 +207,12 @@ void FileWriter::DidTruncate() {
if (position() > length())
SetPosition(length());
operation_in_progress_ = kOperationNone;
- SignalCompletion(FileError::kOK);
+ SignalCompletion(base::File::FILE_OK);
}
-void FileWriter::DidFail(WebFileError code) {
+void FileWriter::DidFailImpl(base::File::Error error) {
DCHECK_NE(kOperationNone, operation_in_progress_);
- DCHECK_NE(FileError::kOK, static_cast<FileError::ErrorCode>(code));
+ DCHECK_NE(base::File::FILE_OK, error);
if (operation_in_progress_ == kOperationAbort) {
CompleteAbort();
return;
@@ -225,7 +221,29 @@ void FileWriter::DidFail(WebFileError code) {
DCHECK_EQ(kWriting, ready_state_);
blob_being_written_.Clear();
operation_in_progress_ = kOperationNone;
- SignalCompletion(static_cast<FileError::ErrorCode>(code));
+ SignalCompletion(error);
+}
+
+void FileWriter::DoTruncate(const KURL& path, int64_t offset) {
+ FileSystemDispatcher::From(GetExecutionContext())
+ .Truncate(path, offset, &request_id_,
+ WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this)));
+}
+
+void FileWriter::DoWrite(const KURL& path,
+ const String& blob_id,
+ int64_t offset) {
+ FileSystemDispatcher::From(GetExecutionContext())
+ .Write(
+ path, blob_id, offset, &request_id_,
+ WTF::BindRepeating(&FileWriter::DidWrite, WrapWeakPersistent(this)),
+ WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this)));
+}
+
+void FileWriter::DoCancel() {
+ FileSystemDispatcher::From(GetExecutionContext())
+ .Cancel(request_id_,
+ WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this)));
}
void FileWriter::CompleteAbort() {
@@ -244,13 +262,13 @@ void FileWriter::DoOperation(Operation operation) {
DCHECK_EQ(-1, truncate_length_);
DCHECK(blob_being_written_.Get());
DCHECK_EQ(kWriting, ready_state_);
- Writer()->Write(position(), blob_being_written_->Uuid());
+ Write(position(), blob_being_written_->Uuid());
break;
case kOperationTruncate:
DCHECK_EQ(kOperationNone, operation_in_progress_);
DCHECK_GE(truncate_length_, 0);
DCHECK_EQ(kWriting, ready_state_);
- Writer()->Truncate(truncate_length_);
+ Truncate(truncate_length_);
break;
case kOperationNone:
DCHECK_EQ(kOperationNone, operation_in_progress_);
@@ -261,7 +279,7 @@ void FileWriter::DoOperation(Operation operation) {
case kOperationAbort:
if (operation_in_progress_ == kOperationWrite ||
operation_in_progress_ == kOperationTruncate)
- Writer()->Cancel();
+ Cancel();
else if (operation_in_progress_ != kOperationAbort)
operation = kOperationNone;
queued_operation_ = kOperationNone;
@@ -273,12 +291,12 @@ void FileWriter::DoOperation(Operation operation) {
operation_in_progress_ = operation;
}
-void FileWriter::SignalCompletion(FileError::ErrorCode code) {
+void FileWriter::SignalCompletion(base::File::Error error) {
ready_state_ = kDone;
truncate_length_ = -1;
- if (FileError::kOK != code) {
- error_ = FileError::CreateDOMException(code);
- if (FileError::kAbortErr == code)
+ if (error != base::File::FILE_OK) {
+ error_ = FileError::CreateDOMException(error);
+ if (base::File::FILE_ERROR_ABORT == error)
FireEvent(EventTypeNames::abort);
else
FireEvent(EventTypeNames::error);
@@ -308,11 +326,12 @@ void FileWriter::SetError(FileError::ErrorCode error_code,
void FileWriter::Dispose() {
// Make sure we've actually got something to stop, and haven't already called
// abort().
- if (Writer() && ready_state_ == kWriting) {
+ if (ready_state_ == kWriting) {
DoOperation(kOperationAbort);
ready_state_ = kDone;
}
- ResetWriter();
+ // Prevents any queued operations from running after abort completes.
+ queued_operation_ = kOperationNone;
}
void FileWriter::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
index e8215bd1f97..69c38d342df 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -31,7 +31,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_H_
-#include "third_party/blink/public/platform/web_file_writer_client.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -49,8 +48,7 @@ class ExecutionContext;
class FileWriter final : public EventTargetWithInlineData,
public FileWriterBase,
public ActiveScriptWrappable<FileWriter>,
- public ContextLifecycleObserver,
- public WebFileWriterClient {
+ public ContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FileWriter);
USING_PRE_FINALIZER(FileWriter, Dispose);
@@ -68,10 +66,15 @@ class FileWriter final : public EventTargetWithInlineData,
ReadyState getReadyState() const { return ready_state_; }
DOMException* error() const { return error_.Get(); }
- // WebFileWriterClient
- void DidWrite(long long bytes, bool complete) override;
- void DidTruncate() override;
- void DidFail(WebFileError) override;
+ // FileWriterBase
+ void DidWriteImpl(int64_t bytes, bool complete) override;
+ void DidTruncateImpl() override;
+ void DidFailImpl(base::File::Error error) override;
+ void DoTruncate(const KURL& path, int64_t offset) override;
+ void DoWrite(const KURL& path,
+ const String& blob_id,
+ int64_t offset) override;
+ void DoCancel() override;
// ContextLifecycleObserver
void ContextDestroyed(ExecutionContext*) override;
@@ -108,7 +111,7 @@ class FileWriter final : public EventTargetWithInlineData,
void DoOperation(Operation);
- void SignalCompletion(FileError::ErrorCode);
+ void SignalCompletion(base::File::Error error_code);
void FireEvent(const AtomicString& type);
@@ -127,6 +130,7 @@ class FileWriter final : public EventTargetWithInlineData,
long long recursion_depth_;
double last_progress_notification_time_ms_;
Member<Blob> blob_being_written_;
+ int request_id_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.cc
index 42d7dbd107f..5e01937d035 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.cc
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/modules/filesystem/file_writer_base.h"
#include <memory>
-#include "third_party/blink/public/platform/web_file_writer.h"
#include "third_party/blink/renderer/core/events/progress_event.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
@@ -40,15 +39,16 @@ namespace blink {
FileWriterBase::~FileWriterBase() = default;
-void FileWriterBase::Initialize(std::unique_ptr<WebFileWriter> writer,
- long long length) {
- DCHECK(!writer_);
+void FileWriterBase::Initialize(const KURL& path, long long length) {
DCHECK_GE(length, 0);
- writer_ = std::move(writer);
length_ = length;
+ path_ = path;
}
-FileWriterBase::FileWriterBase() : position_(0) {}
+FileWriterBase::FileWriterBase()
+ : position_(0),
+ operation_(kOperationNone),
+ cancel_state_(kCancelNotInProgress) {}
void FileWriterBase::SeekInternal(long long position) {
if (position > length_)
@@ -60,14 +60,129 @@ void FileWriterBase::SeekInternal(long long position) {
position_ = position;
}
-void FileWriterBase::ResetWriter() {
- writer_ = nullptr;
+void FileWriterBase::Truncate(long long length) {
+ DCHECK_EQ(kOperationNone, operation_);
+ DCHECK_EQ(kCancelNotInProgress, cancel_state_);
+ operation_ = kOperationTruncate;
+ DoTruncate(path_, length);
}
-void FileWriterBase::Dispose() {
- // Need to explicitly destroy m_writer in pre-finalizer, because otherwise it
- // may attempt to call methods on the FileWriter before we are finalized.
- ResetWriter();
+void FileWriterBase::Write(long long position, const String& id) {
+ DCHECK_EQ(kOperationNone, operation_);
+ DCHECK_EQ(kCancelNotInProgress, cancel_state_);
+ operation_ = kOperationWrite;
+ DoWrite(path_, id, position);
+}
+
+// When we cancel a write/truncate, we always get back the result of the write
+// before the result of the cancel, no matter what happens.
+// So we'll get back either
+// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call]
+// followed by failure [of the cancel]; or
+// failure [of the write, either from cancel or other reasons] followed by
+// the result of the cancel.
+// In the write case, there could also be queued up non-terminal DidWrite calls
+// before any of that comes back, but there will always be a terminal write
+// response [success or failure] after them, followed by the cancel result, so
+// we can ignore non-terminal write responses, take the terminal write success
+// or the first failure as the last write response, then know that the next
+// thing to come back is the cancel response. We only notify the
+// AsyncFileWriterClient when it's all over.
+void FileWriterBase::Cancel() {
+ // Check for the cancel passing the previous operation's return in-flight.
+ if (operation_ != kOperationWrite && operation_ != kOperationTruncate)
+ return;
+ if (cancel_state_ != kCancelNotInProgress)
+ return;
+ cancel_state_ = kCancelSent;
+ DoCancel();
+}
+
+void FileWriterBase::DidFinish(base::File::Error error_code) {
+ if (error_code == base::File::FILE_OK)
+ DidSucceed();
+ else
+ DidFail(error_code);
+}
+
+void FileWriterBase::DidWrite(int64_t bytes, bool complete) {
+ DCHECK_EQ(kOperationWrite, operation_);
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ if (complete)
+ operation_ = kOperationNone;
+ DidWriteImpl(bytes, complete);
+ break;
+ case kCancelSent:
+ // This is the success call of the write, which we'll eat, even though
+ // it succeeded before the cancel got there. We accepted the cancel call,
+ // so the write will eventually return an error.
+ if (complete)
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ default:
+ NOTREACHED();
+ }
+}
+
+void FileWriterBase::DidSucceed() {
+ // Write never gets a DidSucceed call, so this is either a cancel or truncate
+ // response.
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ // A truncate succeeded, with no complications.
+ DCHECK_EQ(kOperationTruncate, operation_);
+ operation_ = kOperationNone;
+ DidTruncateImpl();
+ break;
+ case kCancelSent:
+ DCHECK_EQ(kOperationTruncate, operation_);
+ // This is the success call of the truncate, which we'll eat, even though
+ // it succeeded before the cancel got there. We accepted the cancel call,
+ // so the truncate will eventually return an error.
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ // This is the success of the cancel operation.
+ FinishCancel();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void FileWriterBase::DidFail(base::File::Error error_code) {
+ DCHECK_NE(kOperationNone, operation_);
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ // A write or truncate failed.
+ operation_ = kOperationNone;
+ DidFailImpl(error_code);
+ break;
+ case kCancelSent:
+ // This is the failure of a write or truncate; the next message should be
+ // the result of the cancel. We don't assume that it'll be a success, as
+ // the write/truncate could have failed for other reasons.
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ // The cancel reported failure, meaning that the write or truncate
+ // finished before the cancel got there. But we suppressed the
+ // write/truncate's response, and will now report that it was cancelled.
+ FinishCancel();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void FileWriterBase::FinishCancel() {
+ DCHECK_EQ(kCancelReceivedWriteResponse, cancel_state_);
+ DCHECK_NE(kOperationNone, operation_);
+ cancel_state_ = kCancelNotInProgress;
+ operation_ = kOperationNone;
+ DidFailImpl(base::File::FILE_ERROR_ABORT);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
index 0e608ce3fb1..03e1b25cf82 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h
@@ -32,43 +32,72 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_BASE_H_
#include <memory>
+#include "base/files/file.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
-class WebFileWriter;
-
-class FileWriterBase : public GarbageCollectedMixin {
- USING_PRE_FINALIZER(FileWriterBase, Dispose);
-
+class MODULES_EXPORT FileWriterBase : public GarbageCollectedMixin {
public:
virtual ~FileWriterBase();
- void Initialize(std::unique_ptr<WebFileWriter>, long long length);
+ void Initialize(const KURL& path, long long length);
long long position() const { return position_; }
long long length() const { return length_; }
void Trace(blink::Visitor* visitor) override {}
+ virtual void Truncate(long long length);
+ virtual void Write(long long position, const String& id);
+ virtual void Cancel();
+
protected:
FileWriterBase();
- WebFileWriter* Writer() { return writer_.get(); }
-
void SetPosition(long long position) { position_ = position; }
void SetLength(long long length) { length_ = length; }
void SeekInternal(long long position);
- void ResetWriter();
+ // This calls DidSucceed() or DidFail() based on the value of |error_code|.
+ void DidFinish(base::File::Error error_code);
+ void DidSucceed();
+ void DidWrite(int64_t bytes, bool complete);
+ void DidFail(base::File::Error error_code);
+
+ // Derived classes must provide these methods to asynchronously perform
+ // the requested operation, and they must call the appropriate DidSomething
+ // method upon completion and as progress is made in the Write case.
+ virtual void DoTruncate(const KURL& path, int64_t offset) = 0;
+ virtual void DoWrite(const KURL& path,
+ const String& blob_id,
+ int64_t offset) = 0;
+ virtual void DoCancel() = 0;
+
+ // These are conditionally called by the Did* methods.
+ virtual void DidWriteImpl(int64_t bytes, bool complete) = 0;
+ virtual void DidFailImpl(base::File::Error error_code) = 0;
+ virtual void DidTruncateImpl() = 0;
private:
- void Dispose();
+ enum OperationType { kOperationNone, kOperationWrite, kOperationTruncate };
+
+ enum CancelState {
+ kCancelNotInProgress,
+ kCancelSent,
+ kCancelReceivedWriteResponse,
+ };
+
+ void FinishCancel();
- std::unique_ptr<WebFileWriter> writer_;
long long position_;
long long length_;
+ KURL path_;
+ OperationType operation_;
+ CancelState cancel_state_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
index 85377d37a0e..e9c20b16cc1 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
@@ -30,20 +30,19 @@
#include "third_party/blink/renderer/modules/filesystem/file_writer_sync.h"
-#include "third_party/blink/public/platform/web_file_writer.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
void FileWriterSync::write(Blob* data, ExceptionState& exception_state) {
DCHECK(data);
- DCHECK(Writer());
DCHECK(complete_);
PrepareForWrite();
- Writer()->Write(position(), data->Uuid());
+ Write(position(), data->Uuid());
DCHECK(complete_);
if (error_) {
FileError::ThrowDOMException(exception_state, error_);
@@ -55,14 +54,12 @@ void FileWriterSync::write(Blob* data, ExceptionState& exception_state) {
}
void FileWriterSync::seek(long long position, ExceptionState& exception_state) {
- DCHECK(Writer());
DCHECK(complete_);
SeekInternal(position);
}
void FileWriterSync::truncate(long long offset,
ExceptionState& exception_state) {
- DCHECK(Writer());
DCHECK(complete_);
if (offset < 0) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -70,7 +67,7 @@ void FileWriterSync::truncate(long long offset,
return;
}
PrepareForWrite();
- Writer()->Truncate(offset);
+ Truncate(offset);
DCHECK(complete_);
if (error_) {
FileError::ThrowDOMException(exception_state, error_);
@@ -81,30 +78,57 @@ void FileWriterSync::truncate(long long offset,
SetLength(offset);
}
-void FileWriterSync::DidWrite(long long bytes, bool complete) {
- DCHECK_EQ(FileError::kOK, error_);
+void FileWriterSync::DidWriteImpl(int64_t bytes, bool complete) {
+ DCHECK_EQ(base::File::FILE_OK, error_);
DCHECK(!complete_);
complete_ = complete;
}
-void FileWriterSync::DidTruncate() {
- DCHECK_EQ(FileError::kOK, error_);
+void FileWriterSync::DidTruncateImpl() {
+ DCHECK_EQ(base::File::FILE_OK, error_);
DCHECK(!complete_);
complete_ = true;
}
-void FileWriterSync::DidFail(WebFileError error) {
- DCHECK_EQ(FileError::kOK, error_);
- error_ = static_cast<FileError::ErrorCode>(error);
+void FileWriterSync::DidFailImpl(base::File::Error error) {
+ DCHECK_EQ(base::File::FILE_OK, error_);
+ error_ = error;
DCHECK(!complete_);
complete_ = true;
}
-FileWriterSync::FileWriterSync() : error_(FileError::kOK), complete_(true) {}
+void FileWriterSync::DoTruncate(const KURL& path, int64_t offset) {
+ if (!GetExecutionContext())
+ return;
+ FileSystemDispatcher::From(GetExecutionContext())
+ .TruncateSync(
+ path, offset,
+ WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this)));
+}
+
+void FileWriterSync::DoWrite(const KURL& path,
+ const String& blob_id,
+ int64_t offset) {
+ if (!GetExecutionContext())
+ return;
+ FileSystemDispatcher::From(GetExecutionContext())
+ .WriteSync(
+ path, blob_id, offset,
+ WTF::BindRepeating(&FileWriterSync::DidWrite,
+ WrapWeakPersistent(this)),
+ WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this)));
+}
+
+void FileWriterSync::DoCancel() {
+ NOTREACHED();
+}
+
+FileWriterSync::FileWriterSync(ExecutionContext* context)
+ : ContextClient(context), error_(base::File::FILE_OK), complete_(true) {}
void FileWriterSync::PrepareForWrite() {
DCHECK(complete_);
- error_ = FileError::kOK;
+ error_ = base::File::FILE_OK;
complete_ = false;
}
@@ -113,6 +137,7 @@ FileWriterSync::~FileWriterSync() = default;
void FileWriterSync::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
FileWriterBase::Trace(visitor);
+ ContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
index 1d6bf25fb73..656160699d8 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
@@ -31,7 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_
-#include "third_party/blink/public/platform/web_file_writer_client.h"
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer_base.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -44,30 +44,36 @@ class ExceptionState;
class FileWriterSync final : public ScriptWrappable,
public FileWriterBase,
- public WebFileWriterClient {
+ public ContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FileWriterSync);
public:
- static FileWriterSync* Create() { return new FileWriterSync(); }
+ static FileWriterSync* Create(ExecutionContext* context) {
+ return new FileWriterSync(context);
+ }
~FileWriterSync() override;
void Trace(blink::Visitor*) override;
- // FileWriterBase
void write(Blob*, ExceptionState&);
void seek(long long position, ExceptionState&);
void truncate(long long length, ExceptionState&);
- // WebFileWriterClient, via FileWriterBase
- void DidWrite(long long bytes, bool complete) override;
- void DidTruncate() override;
- void DidFail(WebFileError) override;
+ // FileWriterBase
+ void DidWriteImpl(int64_t bytes, bool complete) override;
+ void DidTruncateImpl() override;
+ void DidFailImpl(base::File::Error error) override;
+ void DoTruncate(const KURL& path, int64_t offset) override;
+ void DoWrite(const KURL& path,
+ const String& blob_id,
+ int64_t offset) override;
+ void DoCancel() override;
private:
- FileWriterSync();
+ explicit FileWriterSync(ExecutionContext* context);
void PrepareForWrite();
- FileError::ErrorCode error_;
+ base::File::Error error_;
bool complete_;
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc
new file mode 100644
index 00000000000..efd3679bafa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc
@@ -0,0 +1,353 @@
+// 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 "third_party/blink/renderer/modules/filesystem/file_writer_base.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+// We use particular offsets to trigger particular behaviors
+// in the TestableFileWriter.
+const int kNoOffset = -1;
+const int kBasicFileTruncate_Offset = 1;
+const int kErrorFileTruncate_Offset = 2;
+const int kCancelFileTruncate_Offset = 3;
+const int kCancelFailedTruncate_Offset = 4;
+const int kBasicFileWrite_Offset = 1;
+const int kErrorFileWrite_Offset = 2;
+const int kMultiFileWrite_Offset = 3;
+const int kCancelFileWriteBeforeCompletion_Offset = 4;
+const int kCancelFileWriteAfterCompletion_Offset = 5;
+
+KURL mock_path_as_kurl() {
+ return KURL("MockPath");
+}
+
+} // namespace
+
+class TestableFileWriter : public GarbageCollectedFinalized<TestableFileWriter>,
+ public FileWriterBase {
+ USING_GARBAGE_COLLECTED_MIXIN(TestableFileWriter);
+
+ public:
+ explicit TestableFileWriter() { reset(); }
+
+ void reset() {
+ received_truncate_ = false;
+ received_truncate_path_ = KURL();
+ received_truncate_offset_ = kNoOffset;
+ received_write_ = false;
+ received_write_path_ = KURL();
+ received_write_offset_ = kNoOffset;
+ received_write_blob_uuid_ = String();
+ received_cancel_ = false;
+
+ received_did_write_count_ = 0;
+ received_did_write_bytes_total_ = 0;
+ received_did_write_complete_ = false;
+ received_did_truncate_ = false;
+ received_did_fail_ = false;
+ fail_error_received_ = static_cast<base::File::Error>(0);
+ }
+
+ void Trace(Visitor* visitor) override { FileWriterBase::Trace(visitor); }
+
+ bool received_truncate_;
+ KURL received_truncate_path_;
+ int64_t received_truncate_offset_;
+ bool received_write_;
+ KURL received_write_path_;
+ String received_write_blob_uuid_;
+ int64_t received_write_offset_;
+ bool received_cancel_;
+
+ int received_did_write_count_;
+ long long received_did_write_bytes_total_;
+ bool received_did_write_complete_;
+ bool received_did_truncate_;
+ bool received_did_fail_;
+ base::File::Error fail_error_received_;
+
+ protected:
+ void DoTruncate(const KURL& path, int64_t offset) override {
+ received_truncate_ = true;
+ received_truncate_path_ = path;
+ received_truncate_offset_ = offset;
+
+ if (offset == kBasicFileTruncate_Offset) {
+ DidSucceed();
+ } else if (offset == kErrorFileTruncate_Offset) {
+ DidFail(base::File::FILE_ERROR_NOT_FOUND);
+ } else if (offset == kCancelFileTruncate_Offset) {
+ Cancel();
+ DidSucceed(); // truncate completion
+ DidSucceed(); // cancel completion
+ } else if (offset == kCancelFailedTruncate_Offset) {
+ Cancel();
+ DidFail(base::File::FILE_ERROR_NOT_FOUND); // truncate completion
+ DidSucceed(); // cancel completion
+ } else {
+ FAIL();
+ }
+ }
+
+ void DoWrite(const KURL& path,
+ const String& blob_uuid,
+ int64_t offset) override {
+ received_write_ = true;
+ received_write_path_ = path;
+ received_write_offset_ = offset;
+ received_write_blob_uuid_ = blob_uuid;
+
+ if (offset == kBasicFileWrite_Offset) {
+ DidWrite(1, true);
+ } else if (offset == kErrorFileWrite_Offset) {
+ DidFail(base::File::FILE_ERROR_NOT_FOUND);
+ } else if (offset == kMultiFileWrite_Offset) {
+ DidWrite(1, false);
+ DidWrite(1, false);
+ DidWrite(1, true);
+ } else if (offset == kCancelFileWriteBeforeCompletion_Offset) {
+ DidWrite(1, false);
+ Cancel();
+ DidWrite(1, false);
+ DidWrite(1, false);
+ DidFail(base::File::FILE_ERROR_NOT_FOUND); // write completion
+ DidSucceed(); // cancel completion
+ } else if (offset == kCancelFileWriteAfterCompletion_Offset) {
+ DidWrite(1, false);
+ Cancel();
+ DidWrite(1, false);
+ DidWrite(1, false);
+ DidWrite(1, true); // write completion
+ DidFail(base::File::FILE_ERROR_NOT_FOUND); // cancel completion
+ } else {
+ FAIL();
+ }
+ }
+
+ void DoCancel() override { received_cancel_ = true; }
+
+ void DidWriteImpl(int64_t bytes, bool complete) override {
+ EXPECT_FALSE(received_did_write_complete_);
+ ++received_did_write_count_;
+ received_did_write_bytes_total_ += bytes;
+ if (complete)
+ received_did_write_complete_ = true;
+ }
+
+ void DidTruncateImpl() override {
+ EXPECT_FALSE(received_did_truncate_);
+ received_did_truncate_ = true;
+ }
+
+ void DidFailImpl(base::File::Error error) override {
+ EXPECT_FALSE(received_did_fail_);
+ received_did_fail_ = true;
+ fail_error_received_ = error;
+ }
+};
+
+class FileWriterTest : public testing::Test {
+ public:
+ FileWriterTest() = default;
+
+ FileWriterBase* writer() { return testable_writer_.Get(); }
+
+ protected:
+ void SetUp() override {
+ testable_writer_ = new TestableFileWriter();
+ testable_writer_->Initialize(mock_path_as_kurl(), 10);
+ }
+
+ Persistent<TestableFileWriter> testable_writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileWriterTest);
+};
+
+TEST_F(FileWriterTest, BasicFileWrite) {
+ const String kBlobId("1234");
+ writer()->Write(kBasicFileWrite_Offset, kBlobId);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_write_);
+ EXPECT_EQ(testable_writer_->received_write_path_, mock_path_as_kurl());
+ EXPECT_EQ(kBasicFileWrite_Offset, testable_writer_->received_write_offset_);
+ EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
+ EXPECT_FALSE(testable_writer_->received_truncate_);
+ EXPECT_FALSE(testable_writer_->received_cancel_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_EQ(1, testable_writer_->received_did_write_count_);
+ EXPECT_TRUE(testable_writer_->received_did_write_complete_);
+ EXPECT_EQ(1, testable_writer_->received_did_write_bytes_total_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+ EXPECT_FALSE(testable_writer_->received_did_fail_);
+}
+
+TEST_F(FileWriterTest, BasicFileTruncate) {
+ writer()->Truncate(kBasicFileTruncate_Offset);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_truncate_);
+ EXPECT_EQ(mock_path_as_kurl(), testable_writer_->received_truncate_path_);
+ EXPECT_EQ(kBasicFileTruncate_Offset,
+ testable_writer_->received_truncate_offset_);
+ EXPECT_FALSE(testable_writer_->received_write_);
+ EXPECT_FALSE(testable_writer_->received_cancel_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_truncate_);
+ EXPECT_EQ(0, testable_writer_->received_did_write_count_);
+ EXPECT_FALSE(testable_writer_->received_did_fail_);
+}
+
+TEST_F(FileWriterTest, ErrorFileWrite) {
+ const String kBlobId("1234");
+ writer()->Write(kErrorFileWrite_Offset, kBlobId);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_write_);
+ EXPECT_EQ(testable_writer_->received_write_path_, mock_path_as_kurl());
+ EXPECT_EQ(kErrorFileWrite_Offset, testable_writer_->received_write_offset_);
+ EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
+ EXPECT_FALSE(testable_writer_->received_truncate_);
+ EXPECT_FALSE(testable_writer_->received_cancel_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
+ testable_writer_->fail_error_received_);
+ EXPECT_EQ(0, testable_writer_->received_did_write_count_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+}
+
+TEST_F(FileWriterTest, ErrorFileTruncate) {
+ writer()->Truncate(kErrorFileTruncate_Offset);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_truncate_);
+ EXPECT_EQ(mock_path_as_kurl(), testable_writer_->received_truncate_path_);
+ EXPECT_EQ(kErrorFileTruncate_Offset,
+ testable_writer_->received_truncate_offset_);
+ EXPECT_FALSE(testable_writer_->received_write_);
+ EXPECT_FALSE(testable_writer_->received_cancel_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
+ testable_writer_->fail_error_received_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+ EXPECT_EQ(0, testable_writer_->received_did_write_count_);
+}
+
+TEST_F(FileWriterTest, MultiFileWrite) {
+ const String kBlobId("1234");
+ writer()->Write(kMultiFileWrite_Offset, kBlobId);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_write_);
+ EXPECT_EQ(testable_writer_->received_write_path_, mock_path_as_kurl());
+ EXPECT_EQ(kMultiFileWrite_Offset, testable_writer_->received_write_offset_);
+ EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
+ EXPECT_FALSE(testable_writer_->received_truncate_);
+ EXPECT_FALSE(testable_writer_->received_cancel_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_EQ(3, testable_writer_->received_did_write_count_);
+ EXPECT_TRUE(testable_writer_->received_did_write_complete_);
+ EXPECT_EQ(3, testable_writer_->received_did_write_bytes_total_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+ EXPECT_FALSE(testable_writer_->received_did_fail_);
+}
+
+TEST_F(FileWriterTest, CancelFileWriteBeforeCompletion) {
+ const String kBlobId("1234");
+ writer()->Write(kCancelFileWriteBeforeCompletion_Offset, kBlobId);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_write_);
+ EXPECT_EQ(testable_writer_->received_write_path_, mock_path_as_kurl());
+ EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset,
+ testable_writer_->received_write_offset_);
+ EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
+ EXPECT_TRUE(testable_writer_->received_cancel_);
+ EXPECT_FALSE(testable_writer_->received_truncate_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_ABORT,
+ testable_writer_->fail_error_received_);
+ EXPECT_EQ(1, testable_writer_->received_did_write_count_);
+ EXPECT_FALSE(testable_writer_->received_did_write_complete_);
+ EXPECT_EQ(1, testable_writer_->received_did_write_bytes_total_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+}
+
+TEST_F(FileWriterTest, CancelFileWriteAfterCompletion) {
+ const String kBlobId("1234");
+ writer()->Write(kCancelFileWriteAfterCompletion_Offset, kBlobId);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_write_);
+ EXPECT_EQ(testable_writer_->received_write_path_, mock_path_as_kurl());
+ EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset,
+ testable_writer_->received_write_offset_);
+ EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
+ EXPECT_TRUE(testable_writer_->received_cancel_);
+ EXPECT_FALSE(testable_writer_->received_truncate_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_ABORT,
+ testable_writer_->fail_error_received_);
+ EXPECT_EQ(1, testable_writer_->received_did_write_count_);
+ EXPECT_FALSE(testable_writer_->received_did_write_complete_);
+ EXPECT_EQ(1, testable_writer_->received_did_write_bytes_total_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+}
+
+TEST_F(FileWriterTest, CancelFileTruncate) {
+ writer()->Truncate(kCancelFileTruncate_Offset);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_truncate_);
+ EXPECT_EQ(mock_path_as_kurl(), testable_writer_->received_truncate_path_);
+ EXPECT_EQ(kCancelFileTruncate_Offset,
+ testable_writer_->received_truncate_offset_);
+ EXPECT_TRUE(testable_writer_->received_cancel_);
+ EXPECT_FALSE(testable_writer_->received_write_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_ABORT,
+ testable_writer_->fail_error_received_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+ EXPECT_EQ(0, testable_writer_->received_did_write_count_);
+}
+
+TEST_F(FileWriterTest, CancelFailedTruncate) {
+ writer()->Truncate(kCancelFailedTruncate_Offset);
+
+ // Check that the Do* methods of the derived class get called correctly.
+ EXPECT_TRUE(testable_writer_->received_truncate_);
+ EXPECT_EQ(mock_path_as_kurl(), testable_writer_->received_truncate_path_);
+ EXPECT_EQ(kCancelFailedTruncate_Offset,
+ testable_writer_->received_truncate_offset_);
+ EXPECT_TRUE(testable_writer_->received_cancel_);
+ EXPECT_FALSE(testable_writer_->received_write_);
+
+ // Check that the Did*Impl methods of the client gets called correctly.
+ EXPECT_TRUE(testable_writer_->received_did_fail_);
+ EXPECT_EQ(base::File::FILE_ERROR_ABORT,
+ testable_writer_->fail_error_received_);
+ EXPECT_FALSE(testable_writer_->received_did_truncate_);
+ EXPECT_EQ(0, testable_writer_->received_did_write_count_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/get_system_directory_options.idl b/chromium/third_party/blink/renderer/modules/filesystem/get_system_directory_options.idl
new file mode 100644
index 00000000000..831ac3560fa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/get_system_directory_options.idl
@@ -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.
+
+// https://wicg.github.io/writable-files/#enumdef-systemdirectorytype
+enum SystemDirectoryType {
+ "sandbox"
+};
+
+// https://wicg.github.io/writable-files/#dictdef-getsystemdirectoryoptions
+dictionary GetSystemDirectoryOptions {
+ required SystemDirectoryType type;
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
index 4eb2801f037..c14ff58d913 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
@@ -35,7 +35,6 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_file_system.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -44,19 +43,20 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
-#include "third_party/blink/renderer/modules/filesystem/directory_entry.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_client.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
#include "third_party/blink/renderer/platform/async_file_system_callbacks.h"
#include "third_party/blink/renderer/platform/content_setting_callbacks.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
namespace {
void ReportFailure(std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
- FileError::ErrorCode error) {
+ base::File::Error error) {
callbacks->DidFail(error);
}
@@ -83,13 +83,14 @@ LocalFileSystem::~LocalFileSystem() = default;
void LocalFileSystem::ResolveURL(
ExecutionContext* context,
const KURL& file_system_url,
- std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ SynchronousType type) {
CallbackWrapper* wrapper = new CallbackWrapper(std::move(callbacks));
RequestFileSystemAccessInternal(
context,
WTF::Bind(&LocalFileSystem::ResolveURLInternal,
WrapCrossThreadPersistent(this), WrapPersistent(context),
- file_system_url, WrapPersistent(wrapper)),
+ file_system_url, WrapPersistent(wrapper), type),
WTF::Bind(&LocalFileSystem::FileSystemNotAllowedInternal,
WrapCrossThreadPersistent(this), WrapPersistent(context),
WrapPersistent(wrapper)));
@@ -99,90 +100,19 @@ void LocalFileSystem::RequestFileSystem(
ExecutionContext* context,
mojom::blink::FileSystemType type,
long long size,
- std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
+ std::unique_ptr<AsyncFileSystemCallbacks> callbacks,
+ SynchronousType sync_type) {
CallbackWrapper* wrapper = new CallbackWrapper(std::move(callbacks));
RequestFileSystemAccessInternal(
context,
WTF::Bind(&LocalFileSystem::FileSystemAllowedInternal,
WrapCrossThreadPersistent(this), WrapPersistent(context), type,
- WrapPersistent(wrapper)),
+ WrapPersistent(wrapper), sync_type),
WTF::Bind(&LocalFileSystem::FileSystemNotAllowedInternal,
WrapCrossThreadPersistent(this), WrapPersistent(context),
WrapPersistent(wrapper)));
}
-namespace {
-
-class ChooseEntryCallbacks : public WebFileSystem::ChooseEntryCallbacks {
- public:
- ChooseEntryCallbacks(ScriptPromiseResolver* resolver, bool return_multiple)
- : resolver_(resolver), return_multiple_(return_multiple) {}
-
- void OnSuccess(WebVector<WebFileSystem::FileSystemEntry> entries) override {
- ScriptState::Scope scope(resolver_->GetScriptState());
- if (return_multiple_) {
- Vector<ScriptPromise> result;
- result.ReserveInitialCapacity(entries.size());
- for (const auto& entry : entries)
- result.emplace_back(CreateFileHandle(entry));
- resolver_->Resolve(ScriptPromise::All(resolver_->GetScriptState(), result)
- .GetScriptValue());
- } else {
- DCHECK_EQ(1u, entries.size());
- resolver_->Resolve(CreateFileHandle(entries[0]).GetScriptValue());
- }
- }
-
- void OnError(base::File::Error error) override {
- resolver_->Reject(FileError::CreateDOMException(error));
- }
-
- private:
- ScriptPromise CreateFileHandle(const WebFileSystem::FileSystemEntry& entry) {
- auto* new_resolver =
- ScriptPromiseResolver::Create(resolver_->GetScriptState());
- ScriptPromise result = new_resolver->Promise();
- auto* fs = DOMFileSystem::CreateIsolatedFileSystem(
- resolver_->GetExecutionContext(), entry.file_system_id);
- // TODO(mek): Try to create handle directly rather than having to do more
- // IPCs to get the actual entries.
- fs->GetFile(fs->root(), entry.base_name, FileSystemFlags(),
- new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver),
- new PromiseErrorCallback(new_resolver));
- return result;
- }
-
- Persistent<ScriptPromiseResolver> resolver_;
- bool return_multiple_;
-};
-
-} // namespace
-
-void LocalFileSystem::ChooseEntry(ScriptPromiseResolver* resolver) {
- if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) {
- resolver->Reject(FileError::CreateDOMException(FileError::kAbortErr));
- return;
- }
-
- WebFileSystem* file_system = GetFileSystem();
- if (!file_system) {
- resolver->Reject(FileError::CreateDOMException(FileError::kAbortErr));
- return;
- }
-
- file_system->ChooseEntry(
- Supplement<LocalFrame>::GetSupplementable()->Client()->GetWebFrame(),
- std::make_unique<ChooseEntryCallbacks>(resolver, false));
-}
-
-WebFileSystem* LocalFileSystem::GetFileSystem() const {
- Platform* platform = Platform::Current();
- if (!platform)
- return nullptr;
-
- return platform->FileSystem();
-}
-
void LocalFileSystem::RequestFileSystemAccessInternal(
ExecutionContext* context,
base::OnceClosure allowed,
@@ -205,7 +135,7 @@ void LocalFileSystem::FileSystemNotAvailable(ExecutionContext* context,
context->GetTaskRunner(TaskType::kFileReading)
->PostTask(FROM_HERE,
WTF::Bind(&ReportFailure, WTF::Passed(callbacks->Release()),
- FileError::kAbortErr));
+ base::File::FILE_ERROR_ABORT));
}
void LocalFileSystem::FileSystemNotAllowedInternal(ExecutionContext* context,
@@ -213,34 +143,40 @@ void LocalFileSystem::FileSystemNotAllowedInternal(ExecutionContext* context,
context->GetTaskRunner(TaskType::kFileReading)
->PostTask(FROM_HERE,
WTF::Bind(&ReportFailure, WTF::Passed(callbacks->Release()),
- FileError::kAbortErr));
+ base::File::FILE_ERROR_ABORT));
}
void LocalFileSystem::FileSystemAllowedInternal(
ExecutionContext* context,
mojom::blink::FileSystemType type,
- CallbackWrapper* callbacks) {
- WebFileSystem* file_system = GetFileSystem();
- if (!file_system) {
- FileSystemNotAvailable(context, callbacks);
- return;
- }
+ CallbackWrapper* callbacks,
+ SynchronousType sync_type) {
KURL storage_partition =
KURL(NullURL(), context->GetSecurityOrigin()->ToString());
- file_system->OpenFileSystem(storage_partition,
- static_cast<WebFileSystemType>(type),
- callbacks->Release());
+ std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks =
+ callbacks->Release();
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context);
+ if (sync_type == kSynchronous) {
+ dispatcher.OpenFileSystemSync(storage_partition, type,
+ std::move(async_callbacks));
+ } else {
+ dispatcher.OpenFileSystem(storage_partition, type,
+ std::move(async_callbacks));
+ }
}
void LocalFileSystem::ResolveURLInternal(ExecutionContext* context,
const KURL& file_system_url,
- CallbackWrapper* callbacks) {
- WebFileSystem* file_system = GetFileSystem();
- if (!file_system) {
- FileSystemNotAvailable(context, callbacks);
- return;
+ CallbackWrapper* callbacks,
+ SynchronousType sync_type) {
+ FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context);
+ std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks =
+ callbacks->Release();
+ if (sync_type == kSynchronous) {
+ dispatcher.ResolveURLSync(file_system_url, std::move(async_callbacks));
+ } else {
+ dispatcher.ResolveURL(file_system_url, std::move(async_callbacks));
}
- file_system->ResolveURL(file_system_url, callbacks->Release());
}
LocalFileSystem::LocalFileSystem(LocalFrame& frame,
@@ -263,10 +199,9 @@ void LocalFileSystem::Trace(blink::Visitor* visitor) {
const char LocalFileSystem::kSupplementName[] = "LocalFileSystem";
LocalFileSystem* LocalFileSystem::From(ExecutionContext& context) {
- if (context.IsDocument()) {
+ if (auto* document = DynamicTo<Document>(context)) {
LocalFileSystem* file_system =
- Supplement<LocalFrame>::From<LocalFileSystem>(
- ToDocument(context).GetFrame());
+ Supplement<LocalFrame>::From<LocalFileSystem>(document->GetFrame());
DCHECK(file_system);
return file_system;
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
index f62847ca161..d58080d2066 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -48,8 +48,6 @@ class CallbackWrapper;
class FileSystemClient;
class ExecutionContext;
class KURL;
-class ScriptPromiseResolver;
-class WebFileSystem;
class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
public Supplement<LocalFrame>,
@@ -59,6 +57,8 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
WTF_MAKE_NONCOPYABLE(LocalFileSystem);
public:
+ enum SynchronousType { kAsynchronous, kSynchronous };
+
static const char kSupplementName[];
LocalFileSystem(LocalFrame&, std::unique_ptr<FileSystemClient>);
@@ -67,13 +67,13 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
void ResolveURL(ExecutionContext*,
const KURL&,
- std::unique_ptr<AsyncFileSystemCallbacks>);
+ std::unique_ptr<AsyncFileSystemCallbacks>,
+ SynchronousType sync_type);
void RequestFileSystem(ExecutionContext*,
mojom::blink::FileSystemType,
long long size,
- std::unique_ptr<AsyncFileSystemCallbacks>);
-
- void ChooseEntry(ScriptPromiseResolver*);
+ std::unique_ptr<AsyncFileSystemCallbacks>,
+ SynchronousType sync_type);
FileSystemClient& Client() const { return *client_; }
@@ -83,7 +83,6 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
const char* NameInHeapSnapshot() const override { return "LocalFileSystem"; }
private:
- WebFileSystem* GetFileSystem() const;
void FileSystemNotAvailable(ExecutionContext*, CallbackWrapper*);
void RequestFileSystemAccessInternal(ExecutionContext*,
@@ -92,8 +91,12 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
void FileSystemNotAllowedInternal(ExecutionContext*, CallbackWrapper*);
void FileSystemAllowedInternal(ExecutionContext*,
mojom::blink::FileSystemType,
- CallbackWrapper*);
- void ResolveURLInternal(ExecutionContext*, const KURL&, CallbackWrapper*);
+ CallbackWrapper*,
+ SynchronousType sync_type);
+ void ResolveURLInternal(ExecutionContext*,
+ const KURL&,
+ CallbackWrapper*,
+ SynchronousType sync_type);
const std::unique_ptr<FileSystemClient> client_;
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc
index 06df6256824..ab6d6ec45b5 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc
@@ -54,7 +54,8 @@ LocalFileSystemClient::~LocalFileSystemClient() = default;
bool LocalFileSystemClient::RequestFileSystemAccessSync(
ExecutionContext* context) {
DCHECK(context);
- if (context->IsDocument()) {
+ if (IsA<Document>(context)) {
+ // TODO(dcheng): Why is this NOTREACHED and handled?
NOTREACHED();
return false;
}
@@ -68,12 +69,13 @@ void LocalFileSystemClient::RequestFileSystemAccessAsync(
ExecutionContext* context,
std::unique_ptr<ContentSettingCallbacks> callbacks) {
DCHECK(context);
- if (!context->IsDocument()) {
+ auto* document = DynamicTo<Document>(context);
+ if (!document) {
+ // TODO(dcheng): Why is this NOTREACHED and handled?
NOTREACHED();
return;
}
- Document* document = ToDocument(context);
DCHECK(document->GetFrame());
document->GetFrame()
->GetContentSettingsClient()
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
index 4a5335d2835..c01ed1c6d63 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h
@@ -56,7 +56,7 @@ class DOMFileSystemCallbacksSyncHelper final
ErrorCallbackBase* GetErrorCallback() { return new ErrorCallbackImpl(this); }
CallbackArg* GetResultOrThrow(ExceptionState& exception_state) {
- if (error_code_ != FileError::ErrorCode::kOK) {
+ if (error_code_ != base::File::FILE_OK) {
FileError::ThrowDOMException(exception_state, error_code_);
return nullptr;
}
@@ -90,8 +90,8 @@ class DOMFileSystemCallbacksSyncHelper final
visitor->Trace(helper_);
ErrorCallbackBase::Trace(visitor);
}
- void Invoke(FileError::ErrorCode error_code) override {
- DCHECK_NE(error_code, FileError::ErrorCode::kOK);
+ void Invoke(base::File::Error error_code) override {
+ DCHECK_NE(error_code, base::File::FILE_OK);
helper_->error_code_ = error_code;
}
@@ -106,7 +106,7 @@ class DOMFileSystemCallbacksSyncHelper final
DOMFileSystemCallbacksSyncHelper() = default;
Member<CallbackArg> result_;
- FileError::ErrorCode error_code_ = FileError::ErrorCode::kOK;
+ base::File::Error error_code_ = base::File::FILE_OK;
friend class SuccessCallbackImpl;
friend class ErrorCallbackImpl;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl b/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
index 39bd2744cfb..935f48bcb00 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
@@ -38,10 +38,8 @@
[RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url,
EntryCallback successCallback, optional ErrorCallback? errorCallback);
- // https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
- // TODO(crbug.com/878581): This needs some kind of options dictionary.
- // TODO(crbug.com/878566): This should be SecureContext, but that is
- // currently broken.
- [RuntimeEnabled=WritableFiles, CallWith=ScriptState]
- Promise<(FileSystemBaseHandle or sequence<FileSystemBaseHandle>)> chooseFileSystemEntries();
+ // https://wicg.github.io/writable-files/#api-choosefilesystementries
+ [RuntimeEnabled=WritableFiles, CallWith=ScriptState, SecureContext]
+ Promise<(FileSystemBaseHandle or sequence<FileSystemBaseHandle>)>
+ chooseFileSystemEntries(optional ChooseFileSystemEntriesOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
index 26b2ce2eeea..713954c0e53 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
@@ -55,7 +55,7 @@ void WorkerGlobalScopeFileSystem::webkitRequestFileSystem(
if (!secure_context->GetSecurityOrigin()->CanAccessFileSystem()) {
DOMFileSystem::ReportError(&worker,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kSecurityErr);
+ base::File::FILE_ERROR_SECURITY);
return;
} else if (secure_context->GetSecurityOrigin()->IsLocal()) {
UseCounter::Count(secure_context, WebFeature::kFileAccessedFileSystem);
@@ -66,7 +66,7 @@ void WorkerGlobalScopeFileSystem::webkitRequestFileSystem(
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
DOMFileSystem::ReportError(&worker,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kInvalidModificationErr);
+ base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
@@ -75,8 +75,8 @@ void WorkerGlobalScopeFileSystem::webkitRequestFileSystem(
FileSystemCallbacks::Create(
FileSystemCallbacks::OnDidOpenFileSystemV8Impl::Create(
success_callback),
- ScriptErrorCallback::Wrap(error_callback), &worker,
- file_system_type));
+ ScriptErrorCallback::Wrap(error_callback), &worker, file_system_type),
+ LocalFileSystem::kAsynchronous);
}
DOMFileSystemSync* WorkerGlobalScopeFileSystem::webkitRequestFileSystemSync(
@@ -107,10 +107,10 @@ DOMFileSystemSync* WorkerGlobalScopeFileSystem::webkitRequestFileSystemSync(
FileSystemCallbacks::Create(sync_helper->GetSuccessCallback(),
sync_helper->GetErrorCallback(), &worker,
file_system_type);
- callbacks->SetShouldBlockUntilCompletion(true);
- LocalFileSystem::From(worker)->RequestFileSystem(&worker, file_system_type,
- size, std::move(callbacks));
+ LocalFileSystem::From(worker)->RequestFileSystem(
+ &worker, file_system_type, size, std::move(callbacks),
+ LocalFileSystem::kSynchronous);
DOMFileSystem* file_system = sync_helper->GetResultOrThrow(exception_state);
return file_system ? DOMFileSystemSync::Create(file_system) : nullptr;
}
@@ -126,7 +126,7 @@ void WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemURL(
!secure_context->GetSecurityOrigin()->CanRequest(completed_url)) {
DOMFileSystem::ReportError(&worker,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kSecurityErr);
+ base::File::FILE_ERROR_SECURITY);
return;
} else if (secure_context->GetSecurityOrigin()->IsLocal()) {
UseCounter::Count(secure_context, WebFeature::kFileAccessedFileSystem);
@@ -135,7 +135,7 @@ void WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemURL(
if (!completed_url.IsValid()) {
DOMFileSystem::ReportError(&worker,
ScriptErrorCallback::Wrap(error_callback),
- FileError::kEncodingErr);
+ base::File::FILE_ERROR_INVALID_URL);
return;
}
@@ -143,7 +143,8 @@ void WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemURL(
&worker, completed_url,
ResolveURICallbacks::Create(
ResolveURICallbacks::OnDidGetEntryV8Impl::Create(success_callback),
- ScriptErrorCallback::Wrap(error_callback), &worker));
+ ScriptErrorCallback::Wrap(error_callback), &worker),
+ LocalFileSystem::kAsynchronous);
}
EntrySync* WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemSyncURL(
@@ -170,10 +171,10 @@ EntrySync* WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemSyncURL(
std::unique_ptr<AsyncFileSystemCallbacks> callbacks =
ResolveURICallbacks::Create(sync_helper->GetSuccessCallback(),
sync_helper->GetErrorCallback(), &worker);
- callbacks->SetShouldBlockUntilCompletion(true);
LocalFileSystem::From(worker)->ResolveURL(&worker, completed_url,
- std::move(callbacks));
+ std::move(callbacks),
+ LocalFileSystem::kSynchronous);
Entry* entry = sync_helper->GetResultOrThrow(exception_state);
return entry ? EntrySync::Create(entry) : nullptr;
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
index f3771a13499..78725b41274 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
@@ -14,9 +14,9 @@ namespace blink {
using device::mojom::blink::GamepadHapticsManager;
GamepadDispatcher& GamepadDispatcher::Instance() {
- DEFINE_STATIC_LOCAL(GamepadDispatcher, gamepad_dispatcher,
+ DEFINE_STATIC_LOCAL(Persistent<GamepadDispatcher>, gamepad_dispatcher,
(new GamepadDispatcher));
- return gamepad_dispatcher;
+ return *gamepad_dispatcher;
}
void GamepadDispatcher::SampleGamepads(device::Gamepads& gamepads) {
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
index 54491f6ad98..c819b8b2456 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc
@@ -93,7 +93,7 @@ void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads& gamepads) {
if (contention_count == kMaximumContentionCount)
break;
} while (gamepad_hardware_buffer_->seqlock.ReadRetry(version));
- UMA_HISTOGRAM_COUNTS("Gamepad.ReadContentionCount", contention_count);
+ UMA_HISTOGRAM_COUNTS_1M("Gamepad.ReadContentionCount", contention_count);
if (contention_count >= kMaximumContentionCount) {
// We failed to successfully read, presumably because the hardware
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
index 71e9b2285ec..66209e12b2f 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -71,12 +71,12 @@ bool HasUserActivation(GamepadList* gamepads) {
// A button press counts as a user activation if the button's value is greater
// than the activation threshold. A threshold is used so that analog buttons
// or triggers do not generate an activation from a light touch.
- for (size_t pad_index = 0; pad_index < gamepads->length(); ++pad_index) {
+ for (wtf_size_t pad_index = 0; pad_index < gamepads->length(); ++pad_index) {
Gamepad* pad = gamepads->item(pad_index);
if (pad) {
const GamepadButtonVector& buttons = pad->buttons();
- for (size_t i = 0; i < buttons.size(); ++i) {
- double value = buttons.at(i)->value();
+ for (auto button : buttons) {
+ double value = button->value();
if (value > kButtonActivationThreshold)
return true;
}
@@ -88,7 +88,7 @@ bool HasUserActivation(GamepadList* gamepads) {
} // namespace
template <typename T>
-static void SampleGamepad(size_t index,
+static void SampleGamepad(unsigned index,
T& gamepad,
const device::Gamepad& device_gamepad,
const TimeTicks& navigation_start) {
@@ -108,6 +108,12 @@ static void SampleGamepad(size_t index,
gamepad.SetPose(device_gamepad.pose);
gamepad.SetHand(device_gamepad.hand);
+ if (device_gamepad.is_xr) {
+ TimeTicks now = TimeTicks::Now();
+ TRACE_COUNTER1("input", "XR gamepad pose age (ms)",
+ (now - last_updated).InMilliseconds());
+ }
+
bool newly_connected;
HasGamepadConnectionChanged(old_id, gamepad.id(), old_was_connected,
gamepad.connected(), &newly_connected, nullptr);
@@ -138,7 +144,7 @@ static void SampleGamepads(ListType* into,
GamepadDispatcher::Instance().SampleGamepads(gamepads);
- for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
+ for (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
device::Gamepad& web_gamepad = gamepads.items[i];
bool hide_xr_gamepad = false;
@@ -210,7 +216,7 @@ GamepadList* NavigatorGamepad::Gamepads() {
// visible.
if (RuntimeEnabledFeatures::UserActivationV2Enabled() && GetFrame() &&
GetPage() && GetPage()->IsPageVisible() && HasUserActivation(gamepads_)) {
- Frame::NotifyUserActivation(GetFrame(), UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetFrame(), UserGestureToken::kNewGesture);
}
return gamepads_.Get();
@@ -384,7 +390,7 @@ void NavigatorGamepad::SampleAndCheckConnectedGamepads() {
bool NavigatorGamepad::CheckConnectedGamepads(GamepadList* old_gamepads,
GamepadList* new_gamepads) {
int disconnection_count = 0;
- for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
+ for (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
Gamepad* old_gamepad = old_gamepads ? old_gamepads->item(i) : nullptr;
Gamepad* new_gamepad = new_gamepads->item(i);
bool connected, disconnected;
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
index b5b03638b30..87bd0323537 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -85,11 +85,12 @@ PositionError* CreatePositionError(
return PositionError::Create(error_code, error);
}
-static void ReportGeolocationViolation(ExecutionContext* context) {
- Document* doc = ToDocumentOrNull(context);
- if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+static void ReportGeolocationViolation(Document* doc) {
+ // TODO(dcheng): |doc| probably can't be null here.
+ if (!LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
+ : nullptr)) {
PerformanceMonitor::ReportGenericViolation(
- context, PerformanceMonitor::kDiscouragedAPIUse,
+ doc, PerformanceMonitor::kDiscouragedAPIUse,
"Only request geolocation information in response to a user gesture.",
base::TimeDelta(), nullptr);
}
@@ -121,7 +122,7 @@ void Geolocation::Trace(blink::Visitor* visitor) {
}
Document* Geolocation::GetDocument() const {
- return ToDocument(GetExecutionContext());
+ return To<Document>(GetExecutionContext());
}
LocalFrame* Geolocation::GetFrame() const {
@@ -224,8 +225,9 @@ void Geolocation::StartRequest(GeoNotifier* notifier) {
return;
}
- if (!GetFrame()->IsFeatureEnabled(mojom::FeaturePolicyFeature::kGeolocation,
- ReportOptions::kReportOnFailure)) {
+ if (!GetDocument()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kGeolocation,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(GetDocument(),
WebFeature::kGeolocationDisabledByFeaturePolicy);
GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
@@ -463,7 +465,7 @@ void Geolocation::UpdateGeolocationConnection() {
invalidator);
geolocation_service_->CreateGeolocation(
MakeRequest(&geolocation_, invalidator),
- Frame::HasTransientUserActivation(GetFrame()));
+ LocalFrame::HasTransientUserActivation(GetFrame()));
geolocation_.set_connection_error_handler(WTF::Bind(
&Geolocation::OnGeolocationConnectionError, WrapWeakPersistent(this)));
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
index e76a6b3f4cd..6cb4156980d 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -345,6 +345,7 @@ void ImageCapture::SetMediaTrackConstraints(
(constraints.hasFocusMode() && !capabilities_.hasFocusMode()) ||
(constraints.hasExposureCompensation() &&
!capabilities_.hasExposureCompensation()) ||
+ (constraints.hasExposureTime() && !capabilities_.hasExposureTime()) ||
(constraints.hasColorTemperature() &&
!capabilities_.hasColorTemperature()) ||
(constraints.hasIso() && !capabilities_.hasIso()) ||
@@ -352,6 +353,7 @@ void ImageCapture::SetMediaTrackConstraints(
(constraints.hasContrast() && !capabilities_.hasContrast()) ||
(constraints.hasSaturation() && !capabilities_.hasSaturation()) ||
(constraints.hasSharpness() && !capabilities_.hasSharpness()) ||
+ (constraints.hasFocusDistance() && !capabilities_.hasFocusDistance()) ||
(constraints.hasZoom() && !capabilities_.hasZoom()) ||
(constraints.hasTorch() && !capabilities_.hasTorch())) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotSupportedError,
@@ -436,6 +438,20 @@ void ImageCapture::SetMediaTrackConstraints(
constraints.exposureCompensation());
settings->exposure_compensation = exposure_compensation;
}
+ settings->has_exposure_time =
+ constraints.hasExposureTime() && constraints.exposureTime().IsDouble();
+ if (settings->has_exposure_time) {
+ const auto exposure_time = constraints.exposureTime().GetAsDouble();
+ if (exposure_time < capabilities_.exposureTime()->min() ||
+ exposure_time > capabilities_.exposureTime()->max()) {
+ resolver->Reject(
+ DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ "exposureTime setting out of range"));
+ return;
+ }
+ temp_constraints.setExposureTime(constraints.exposureTime());
+ settings->exposure_time = exposure_time;
+ }
settings->has_color_temperature = constraints.hasColorTemperature() &&
constraints.colorTemperature().IsDouble();
if (settings->has_color_temperature) {
@@ -519,6 +535,21 @@ void ImageCapture::SetMediaTrackConstraints(
settings->sharpness = sharpness;
}
+ settings->has_focus_distance =
+ constraints.hasFocusDistance() && constraints.focusDistance().IsDouble();
+ if (settings->has_focus_distance) {
+ const auto focus_distance = constraints.focusDistance().GetAsDouble();
+ if (focus_distance < capabilities_.focusDistance()->min() ||
+ focus_distance > capabilities_.focusDistance()->max()) {
+ resolver->Reject(
+ DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ "focusDistance setting out of range"));
+ return;
+ }
+ temp_constraints.setFocusDistance(constraints.focusDistance());
+ settings->focus_distance = focus_distance;
+ }
+
settings->has_zoom = constraints.hasZoom() && constraints.zoom().IsDouble();
if (settings->has_zoom) {
const auto zoom = constraints.zoom().GetAsDouble();
@@ -585,6 +616,8 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings& settings) const {
if (settings_.hasExposureCompensation())
settings.setExposureCompensation(settings_.exposureCompensation());
+ if (settings_.hasExposureTime())
+ settings.setExposureTime(settings_.exposureTime());
if (settings_.hasColorTemperature())
settings.setColorTemperature(settings_.colorTemperature());
if (settings_.hasIso())
@@ -599,6 +632,8 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings& settings) const {
if (settings_.hasSharpness())
settings.setSharpness(settings_.sharpness());
+ if (settings_.hasFocusDistance())
+ settings.setFocusDistance(settings_.focusDistance());
if (settings_.hasZoom())
settings.setZoom(settings_.zoom());
if (settings_.hasTorch())
@@ -772,6 +807,11 @@ void ImageCapture::UpdateMediaTrackCapabilities(
settings_.setExposureCompensation(
photo_state->exposure_compensation->current);
}
+ if (photo_state->exposure_time->max != photo_state->exposure_time->min) {
+ capabilities_.setExposureTime(
+ MediaSettingsRange::Create(*photo_state->exposure_time));
+ settings_.setExposureTime(photo_state->exposure_time->current);
+ }
if (photo_state->color_temperature->max !=
photo_state->color_temperature->min) {
capabilities_.setColorTemperature(
@@ -804,6 +844,11 @@ void ImageCapture::UpdateMediaTrackCapabilities(
settings_.setSharpness(photo_state->sharpness->current);
}
+ if (photo_state->focus_distance->max != photo_state->focus_distance->min) {
+ capabilities_.setFocusDistance(
+ MediaSettingsRange::Create(*photo_state->focus_distance));
+ settings_.setFocusDistance(photo_state->focus_distance->current);
+ }
if (photo_state->zoom->max != photo_state->zoom->min) {
capabilities_.setZoom(MediaSettingsRange::Create(*photo_state->zoom));
settings_.setZoom(photo_state->zoom->current);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/README.md b/chromium/third_party/blink/renderer/modules/indexeddb/README.md
index 39c3c33a6db..d38cacc99e7 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/README.md
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/README.md
@@ -28,4 +28,14 @@ Please add documents below as you write it.
Please complete the list below with new or existing design docs.
-* [Handling Large Values in IndexedDB](https://goo.gl/VncHrw)
+* [Handling Large Values in IndexedDB](https://docs.google.com/document/d/1wmbLb91Se4OIp3Z0eKkAJEHG4YHgq75WUH2mqazrnik/)
+* [IndexedDB Tombstone Sweeper](https://docs.google.com/document/d/1BWy0aT_hWrmc3umCxas6-7ofDmT8CSgK4sv1s4VwTeA/)
+* [LevelDB Scopes: Special Transactions for IndexedDB](https://docs.google.com/document/d/16_igCI15Gfzb6UYqeuJTmJPrzEtawz6Y1tVOKNtYgiU/)
+* [IndexedDB: Onion Soup](https://docs.google.com/document/d/12nwW3mLxVBximpIt9IS0h7hoaB5fcIAl4zHdhuOVKLg/)
+
+## Obsoleted Design Docs
+
+These documents are no longer current, but are still the best documentation we
+have in their area.
+
+* [Blob Storage in IndexedDB](https://docs.google.com/document/d/1Kdr4pcFt4QBDLLQn-fY4kZgw6ptmK23lthGZdQMVh2Y/) \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
index 6a1da96df88..db3a230190b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -50,6 +50,7 @@
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/atomics.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include <limits>
#include <memory>
@@ -192,7 +193,8 @@ void IDBDatabase::OnChanges(
WebVector<WebIDBObservation> web_observations,
const WebIDBDatabaseCallbacks::TransactionMap& transactions) {
HeapVector<Member<IDBObservation>> observations;
- observations.ReserveInitialCapacity(web_observations.size());
+ observations.ReserveInitialCapacity(
+ SafeCast<wtf_size_t>(web_observations.size()));
for (WebIDBObservation& web_observation : web_observations) {
observations.emplace_back(
IDBObservation::Create(std::move(web_observation), isolate_));
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
index 67f5ea8fdb2..5504e123547 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
@@ -30,17 +30,18 @@
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
DispatchEventResult IDBEventDispatcher::Dispatch(
Event& event,
HeapVector<Member<EventTarget>>& event_targets) {
- size_t size = event_targets.size();
+ wtf_size_t size = event_targets.size();
DCHECK(size);
event.SetEventPhase(Event::kCapturingPhase);
- for (size_t i = size - 1; i; --i) { // Don't do the first element.
+ for (wtf_size_t i = size - 1; i; --i) { // Don't do the first element.
event.SetCurrentTarget(event_targets[i].Get());
event_targets[i]->FireEventListeners(event);
if (event.PropagationStopped())
@@ -54,7 +55,7 @@ DispatchEventResult IDBEventDispatcher::Dispatch(
goto doneDispatching;
event.SetEventPhase(Event::kBubblingPhase);
- for (size_t i = 1; i < size; ++i) { // Don't do the first element.
+ for (wtf_size_t i = 1; i < size; ++i) { // Don't do the first element.
event.SetCurrentTarget(event_targets[i].Get());
event_targets[i]->FireEventListeners(event);
if (event.PropagationStopped() || event.cancelBubble())
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
index 4dd5232c63f..3f70fecdb98 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -56,11 +56,9 @@ static const char kPermissionDeniedErrorMessage[] =
IDBFactory::IDBFactory() = default;
static bool IsContextValid(ExecutionContext* context) {
- DCHECK(context->IsDocument() || context->IsWorkerGlobalScope());
- if (context->IsDocument()) {
- Document* document = ToDocument(context);
+ DCHECK(IsA<Document>(context) || context->IsWorkerGlobalScope());
+ if (auto* document = DynamicTo<Document>(context))
return document->GetFrame() && document->GetPage();
- }
return true;
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
index 114db34fb2a..8ed421c8c74 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
@@ -41,8 +41,8 @@ bool IDBKey::IsValid() const {
return false;
if (type_ == kArrayType) {
- for (size_t i = 0; i < array_.size(); i++) {
- if (!array_[i]->IsValid())
+ for (const auto& element : array_) {
+ if (!element->IsValid())
return false;
}
}
@@ -67,7 +67,8 @@ int IDBKey::Compare(const IDBKey* other) const {
switch (type_) {
case kArrayType:
- for (size_t i = 0; i < array_.size() && i < other->array_.size(); ++i) {
+ for (wtf_size_t i = 0; i < array_.size() && i < other->array_.size();
+ ++i) {
if (int result = array_[i]->Compare(other->array_[i].get()))
return result;
}
@@ -123,7 +124,7 @@ WebVector<WebIDBKey> IDBKey::ToMultiEntryArray(
return static_cast<IDBKey*>(a)->IsLessThan(static_cast<IDBKey*>(b));
});
const auto end = std::unique(result.begin(), result.end());
- DCHECK_LE(static_cast<size_t>(end - result.begin()), result.size());
+ DCHECK_LE(static_cast<wtf_size_t>(end - result.begin()), result.size());
result.resize(end - result.begin());
return result;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
index 3e1c12b4acf..af493f274a8 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
@@ -61,12 +61,12 @@ static inline bool IsIdentifierCharacter(UChar c) {
}
bool IsIdentifier(const String& s) {
- size_t length = s.length();
+ wtf_size_t length = s.length();
if (!length)
return false;
if (!IsIdentifierStartCharacter(s[0]))
return false;
- for (size_t i = 1; i < length; ++i) {
+ for (wtf_size_t i = 1; i < length; ++i) {
if (!IsIdentifierCharacter(s[i]))
return false;
}
@@ -93,8 +93,8 @@ void IDBParseKeyPath(const String& key_path,
}
key_path.Split('.', /*allow_empty_entries=*/true, elements);
- for (size_t i = 0; i < elements.size(); ++i) {
- if (!IsIdentifier(elements[i])) {
+ for (const auto& element : elements) {
+ if (!IsIdentifier(element)) {
error = kIDBKeyPathParseErrorIdentifier;
return;
}
@@ -110,8 +110,8 @@ IDBKeyPath::IDBKeyPath(const class String& string)
IDBKeyPath::IDBKeyPath(const Vector<class String>& array)
: type_(kArrayType), array_(array) {
#if DCHECK_IS_ON()
- for (size_t i = 0; i < array_.size(); ++i)
- DCHECK(!array_[i].IsNull());
+ for (const auto& element : array_)
+ DCHECK(!element.IsNull());
#endif
}
@@ -127,8 +127,8 @@ IDBKeyPath::IDBKeyPath(const StringOrStringSequence& key_path) {
type_ = kArrayType;
array_ = key_path.GetAsStringSequence();
#if DCHECK_IS_ON()
- for (size_t i = 0; i < array_.size(); ++i)
- DCHECK(!array_[i].IsNull());
+ for (const auto& element : array_)
+ DCHECK(!element.IsNull());
#endif
}
}
@@ -177,8 +177,8 @@ bool IDBKeyPath::IsValid() const {
case kArrayType:
if (array_.IsEmpty())
return false;
- for (size_t i = 0; i < array_.size(); ++i) {
- if (!IDBIsValidKeyPath(array_[i]))
+ for (const auto& element : array_) {
+ if (!IDBIsValidKeyPath(element))
return false;
}
return true;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path_test.cc
index 62dfa5829e7..92e1f492f9d 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path_test.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path_test.cc
@@ -49,7 +49,7 @@ void CheckKeyPath(const String& key_path,
if (error != kIDBKeyPathParseErrorNone)
return;
ASSERT_EQ(expected.size(), key_path_elements.size());
- for (size_t i = 0; i < expected.size(); ++i)
+ for (wtf_size_t i = 0; i < expected.size(); ++i)
ASSERT_TRUE(expected[i] == key_path_elements[i]) << i;
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
index edacac192e5..722fa6d674f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -29,6 +29,7 @@
#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
+#include "base/numerics/safe_conversions.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key_range.h"
@@ -557,19 +558,20 @@ IDBRequest* IDBObjectStore::DoPut(ScriptState* script_state,
key_type_histogram.Count(static_cast<int>(key->GetType()));
}
- Vector<int64_t> index_ids;
- WebVector<WebVector<WebIDBKey>> index_keys;
+ WebVector<WebIDBIndexKeys> index_keys;
index_keys.reserve(Metadata().indexes.size());
for (const auto& it : Metadata().indexes) {
if (clone.IsEmpty())
value_wrapper.Clone(script_state, &clone);
- index_ids.push_back(it.key);
- index_keys.emplace_back(GenerateIndexKeysForValue(
- script_state->GetIsolate(), *it.value, clone));
+ index_keys.emplace_back(
+ it.key, GenerateIndexKeysForValue(script_state->GetIsolate(), *it.value,
+ clone));
}
// Records 1KB to 1GB.
- UMA_HISTOGRAM_COUNTS_1M("WebCore.IndexedDB.PutValueSize2",
- value_wrapper.DataLengthBeforeWrapInBytes() / 1024);
+ UMA_HISTOGRAM_COUNTS_1M(
+ "WebCore.IndexedDB.PutValueSize2",
+ base::saturated_cast<base::HistogramBase::Sample>(
+ value_wrapper.DataLengthBeforeWrapInBytes() / 1024));
IDBRequest* request = IDBRequest::Create(
script_state, source, transaction_.Get(), std::move(metrics));
@@ -584,8 +586,7 @@ IDBRequest* IDBObjectStore::DoPut(ScriptState* script_state,
transaction_->Id(), Id(), WebData(value_wrapper.TakeWireBytes()),
value_wrapper.TakeBlobInfo(), WebIDBKeyView(key),
static_cast<WebIDBPutMode>(put_mode),
- request->CreateWebCallbacks().release(), index_ids,
- WebVector<WebIDBDatabase::WebIndexKeys>(std::move(index_keys)));
+ request->CreateWebCallbacks().release(), std::move(index_keys));
return request;
}
@@ -746,8 +747,6 @@ class IndexPopulator final : public EventListener {
if (cursor_any->GetType() == IDBAny::kIDBCursorWithValueType)
cursor = cursor_any->IdbCursorWithValue();
- Vector<int64_t> index_ids;
- index_ids.push_back(IndexMetadata().id);
if (cursor && !cursor->IsDeleted()) {
cursor->Continue(nullptr, nullptr, IDBRequest::AsyncTraceState(),
ASSERT_NO_EXCEPTION);
@@ -755,18 +754,21 @@ class IndexPopulator final : public EventListener {
const IDBKey* primary_key = cursor->IdbPrimaryKey();
ScriptValue value = cursor->value(script_state_);
- WebVector<WebVector<WebIDBKey>> index_keys_list;
- index_keys_list.reserve(1);
- index_keys_list.emplace_back(GenerateIndexKeysForValue(
- script_state_->GetIsolate(), IndexMetadata(), value));
+ WebVector<WebIDBIndexKeys> index_keys;
+ index_keys.reserve(1);
+ index_keys.emplace_back(
+ IndexMetadata().id,
+ GenerateIndexKeysForValue(script_state_->GetIsolate(),
+ IndexMetadata(), value));
- database_->Backend()->SetIndexKeys(
- transaction_id_, object_store_id_, WebIDBKeyView(primary_key),
- index_ids,
- WebVector<WebIDBDatabase::WebIndexKeys>(std::move(index_keys_list)));
+ database_->Backend()->SetIndexKeys(transaction_id_, object_store_id_,
+ WebIDBKeyView(primary_key),
+ std::move(index_keys));
} else {
// Now that we are done indexing, tell the backend to go
// back to processing tasks of type NormalTask.
+ Vector<int64_t> index_ids;
+ index_ids.push_back(IndexMetadata().id);
database_->Backend()->SetIndexesReady(transaction_id_, object_store_id_,
index_ids);
database_.Clear();
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
index 9729f0d46e3..765b6267942 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -430,8 +430,8 @@ void IDBRequest::EnqueueResponse(const Vector<String>& string_list) {
}
DOMStringList* dom_string_list = DOMStringList::Create();
- for (size_t i = 0; i < string_list.size(); ++i)
- dom_string_list->Append(string_list[i]);
+ for (const auto& item : string_list)
+ dom_string_list->Append(item);
EnqueueResultInternal(IDBAny::Create(dom_string_list));
metrics_.RecordAndReset();
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.h
index 2cb8f84ed02..16b7ca15502 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/callback.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_test_helper.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_test_helper.cc
index 7e8b391c681..cf37a961664 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_test_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_test_helper.cc
@@ -36,9 +36,9 @@ std::unique_ptr<IDBValue> CreateNullIDBValueForTesting(v8::Isolate* isolate) {
std::unique_ptr<IDBValue> CreateIDBValueForTesting(v8::Isolate* isolate,
bool create_wrapped_value) {
- size_t element_count = create_wrapped_value ? 16 : 2;
+ uint32_t element_count = create_wrapped_value ? 16 : 2;
v8::Local<v8::Array> v8_array = v8::Array::New(isolate, element_count);
- for (size_t i = 0; i < element_count; ++i)
+ for (uint32_t i = 0; i < element_count; ++i)
v8_array->Set(i, v8::True(isolate));
NonThrowableExceptionState non_throwable_exception_state;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
index 732ed6a1157..6e0e414b36f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
@@ -122,11 +122,13 @@ TEST_F(IDBTransactionTest, ContextDestroyedEarlyDeath) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1u, live_transactions.size());
+ EXPECT_EQ(1u, live_transactions->size());
Persistent<IDBRequest> request =
IDBRequest::Create(scope.GetScriptState(), store_.Get(),
@@ -136,7 +138,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedEarlyDeath) {
request.Clear(); // The transaction is holding onto the request.
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1u, live_transactions.size());
+ EXPECT_EQ(1u, live_transactions->size());
// This will generate an Abort() call to the back end which is dropped by the
// fake proxy, so an explicit OnAbort call is made.
@@ -147,7 +149,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedEarlyDeath) {
store_.Clear();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
TEST_F(IDBTransactionTest, ContextDestroyedAfterDone) {
@@ -156,11 +158,13 @@ TEST_F(IDBTransactionTest, ContextDestroyedAfterDone) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
Persistent<IDBRequest> request =
IDBRequest::Create(scope.GetScriptState(), store_.Get(),
@@ -172,7 +176,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedAfterDone) {
request.Clear(); // The transaction is holding onto the request.
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
// This will generate an Abort() call to the back end which is dropped by the
// fake proxy, so an explicit OnAbort call is made.
@@ -184,10 +188,10 @@ TEST_F(IDBTransactionTest, ContextDestroyedAfterDone) {
// The request completed, so it has enqueued a success event. Discard the
// event, so that the transaction can go away.
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
TEST_F(IDBTransactionTest, ContextDestroyedWithQueuedResult) {
@@ -196,11 +200,13 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithQueuedResult) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
Persistent<IDBRequest> request =
IDBRequest::Create(scope.GetScriptState(), store_.Get(),
@@ -211,7 +217,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithQueuedResult) {
request.Clear(); // The transaction is holding onto the request.
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
// This will generate an Abort() call to the back end which is dropped by the
// fake proxy, so an explicit OnAbort call is made.
@@ -224,7 +230,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithQueuedResult) {
url_loader_mock_factory_->ServeAsynchronousRequests();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
TEST_F(IDBTransactionTest, ContextDestroyedWithTwoQueuedResults) {
@@ -233,11 +239,13 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithTwoQueuedResults) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
Persistent<IDBRequest> request1 =
IDBRequest::Create(scope.GetScriptState(), store_.Get(),
@@ -253,7 +261,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithTwoQueuedResults) {
request1.Clear(); // The transaction is holding onto the requests.
request2.Clear();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
// This will generate an Abort() call to the back end which is dropped by the
// fake proxy, so an explicit OnAbort call is made.
@@ -266,7 +274,7 @@ TEST_F(IDBTransactionTest, ContextDestroyedWithTwoQueuedResults) {
url_loader_mock_factory_->ServeAsynchronousRequests();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
TEST_F(IDBTransactionTest, DocumentShutdownWithQueuedAndBlockedResults) {
@@ -277,11 +285,13 @@ TEST_F(IDBTransactionTest, DocumentShutdownWithQueuedAndBlockedResults) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
Persistent<IDBRequest> request1 =
IDBRequest::Create(scope.GetScriptState(), store_.Get(),
@@ -297,7 +307,7 @@ TEST_F(IDBTransactionTest, DocumentShutdownWithQueuedAndBlockedResults) {
request1.Clear(); // The transaction is holding onto the requests.
request2.Clear();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
// This will generate an Abort() call to the back end which is dropped by the
// fake proxy, so an explicit OnAbort call is made.
@@ -310,7 +320,7 @@ TEST_F(IDBTransactionTest, DocumentShutdownWithQueuedAndBlockedResults) {
url_loader_mock_factory_->ServeAsynchronousRequests();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
TEST_F(IDBTransactionTest, TransactionFinish) {
@@ -320,22 +330,24 @@ TEST_F(IDBTransactionTest, TransactionFinish) {
EXPECT_CALL(*backend, Close()).Times(1);
BuildTransaction(scope, std::move(backend));
- PersistentHeapHashSet<WeakMember<IDBTransaction>> live_transactions;
- live_transactions.insert(transaction_);
+ Persistent<HeapHashSet<WeakMember<IDBTransaction>>> live_transactions =
+ new HeapHashSet<WeakMember<IDBTransaction>>;
+ ;
+ live_transactions->insert(transaction_);
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
DeactivateNewTransactions(scope.GetIsolate());
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
transaction_.Clear();
store_.Clear();
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(1U, live_transactions.size());
+ EXPECT_EQ(1U, live_transactions->size());
// Stop the context, so events don't get queued (which would keep the
// transaction alive).
@@ -348,7 +360,7 @@ TEST_F(IDBTransactionTest, TransactionFinish) {
// OnAbort() should have cleared the transaction's reference to the database.
ThreadState::Current()->CollectAllGarbage();
- EXPECT_EQ(0U, live_transactions.size());
+ EXPECT_EQ(0U, live_transactions->size());
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
index cf13a66dd43..21626735dde 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "v8/include/v8.h"
namespace blink {
@@ -20,7 +21,7 @@ namespace blink {
IDBValue::IDBValue(const WebData& data,
const WebVector<WebBlobInfo>& web_blob_info)
: data_(data) {
- blob_info_.ReserveInitialCapacity(web_blob_info.size());
+ blob_info_.ReserveInitialCapacity(SafeCast<wtf_size_t>(web_blob_info.size()));
for (const WebBlobInfo& info : web_blob_info) {
blob_info_.push_back(info);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
index 7630571fa49..5ab0aacad0c 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_value.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -136,7 +137,7 @@ bool IDBValueWrapper::WrapIfBiggerThan(unsigned max_bytes) {
DCHECK(owns_wire_bytes_) << __func__ << " called after TakeWireBytes()";
#endif // DCHECK_IS_ON()
- unsigned wire_data_size = wire_data_.size();
+ size_t wire_data_size = wire_data_.size();
if (wire_data_size <= max_bytes)
return false;
@@ -154,7 +155,8 @@ bool IDBValueWrapper::WrapIfBiggerThan(unsigned max_bytes) {
wire_data_buffer_.push_back(kVersionTag);
wire_data_buffer_.push_back(kRequiresProcessingSSVPseudoVersion);
wire_data_buffer_.push_back(kReplaceWithBlob);
- IDBValueWrapper::WriteVarInt(wire_data_size, wire_data_buffer_);
+ IDBValueWrapper::WriteVarInt(SafeCast<unsigned>(wire_data_size),
+ wire_data_buffer_);
IDBValueWrapper::WriteVarInt(serialized_value_->BlobDataHandles().size(),
wire_data_buffer_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping_test.cc
index e52b0d133e9..f78b2600392 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping_test.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping_test.cc
@@ -184,7 +184,7 @@ TEST(IDBValueWrapperTest, WriteBytes) {
// Friend class of IDBValueUnwrapper with access to its internals.
class IDBValueUnwrapperReadTestHelper {
public:
- void ReadVarInt(const char* start, size_t buffer_size) {
+ void ReadVarInt(const char* start, uint32_t buffer_size) {
IDBValueUnwrapper unwrapper;
const uint8_t* buffer_start = reinterpret_cast<const uint8_t*>(start);
@@ -197,10 +197,10 @@ class IDBValueUnwrapperReadTestHelper {
<< "ReadVarInt should not change end_";
ASSERT_LE(unwrapper.current_, unwrapper.end_)
<< "ReadVarInt should not move current_ past end_";
- consumed_bytes_ = unwrapper.current_ - buffer_start;
+ consumed_bytes_ = static_cast<uint32_t>(unwrapper.current_ - buffer_start);
}
- void ReadBytes(const char* start, size_t buffer_size) {
+ void ReadBytes(const char* start, uint32_t buffer_size) {
IDBValueUnwrapper unwrapper;
const uint8_t* buffer_start = reinterpret_cast<const uint8_t*>(start);
@@ -212,7 +212,7 @@ class IDBValueUnwrapperReadTestHelper {
ASSERT_EQ(unwrapper.end_, buffer_end) << "ReadBytes should not change end_";
ASSERT_LE(unwrapper.current_, unwrapper.end_)
<< "ReadBytes should not move current_ past end_";
- consumed_bytes_ = unwrapper.current_ - buffer_start;
+ consumed_bytes_ = static_cast<uint32_t>(unwrapper.current_ - buffer_start);
}
bool success() { return success_; }
@@ -488,7 +488,8 @@ TEST(IDBValueUnwrapperTest, IsWrapped) {
wrapped_value->SetIsolate(scope.GetIsolate());
EXPECT_TRUE(IDBValueUnwrapper::IsWrapped(wrapped_value.get()));
- Vector<char> wrapped_marker_bytes(wrapped_marker_buffer->size());
+ Vector<char> wrapped_marker_bytes(
+ static_cast<wtf_size_t>(wrapped_marker_buffer->size()));
ASSERT_TRUE(wrapped_marker_buffer->GetBytes(wrapped_marker_bytes.data(),
wrapped_marker_bytes.size()));
@@ -496,7 +497,7 @@ TEST(IDBValueUnwrapperTest, IsWrapped) {
// Truncating the array to fewer than 3 bytes should cause IsWrapped() to
// return false.
ASSERT_LT(3U, wrapped_marker_bytes.size());
- for (size_t i = 0; i < 3; ++i) {
+ for (wtf_size_t i = 0; i < 3; ++i) {
std::unique_ptr<IDBValue> mutant_value = IDBValue::Create(
SharedBuffer::Create(wrapped_marker_bytes.data(), i), blob_infos);
mutant_value->SetIsolate(scope.GetIsolate());
@@ -507,7 +508,7 @@ TEST(IDBValueUnwrapperTest, IsWrapped) {
// IsWrapped() looks at the first 3 bytes in the value. Flipping any bit in
// these 3 bytes should cause IsWrapped() to return false.
ASSERT_LT(3U, wrapped_marker_bytes.size());
- for (size_t i = 0; i < 3; ++i) {
+ for (wtf_size_t i = 0; i < 3; ++i) {
for (int j = 0; j < 8; ++j) {
char mask = 1 << j;
wrapped_marker_bytes[i] ^= mask;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_client.cc b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_client.cc
index b92e3a87e24..40640a0a548 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_client.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_client.cc
@@ -32,9 +32,8 @@ IndexedDBClient::IndexedDBClient(WorkerClients& clients)
: Supplement<WorkerClients>(clients) {}
IndexedDBClient* IndexedDBClient::From(ExecutionContext* context) {
- if (context->IsDocument()) {
- return Supplement<LocalFrame>::From<IndexedDBClient>(
- ToDocument(*context).GetFrame());
+ if (auto* document = DynamicTo<Document>(context)) {
+ return Supplement<LocalFrame>::From<IndexedDBClient>(document->GetFrame());
}
WorkerClients* clients = ToWorkerGlobalScope(*context).Clients();
@@ -47,8 +46,7 @@ bool IndexedDBClient::AllowIndexedDB(ExecutionContext* context,
DCHECK(context->IsContextThread());
SECURITY_DCHECK(context->IsDocument() || context->IsWorkerGlobalScope());
- if (context->IsDocument()) {
- Document* document = ToDocument(context);
+ if (auto* document = DynamicTo<Document>(context)) {
LocalFrame* frame = document->GetFrame();
if (!frame)
return false;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
index d0776114b01..00ff7182645 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
@@ -141,7 +141,7 @@ class GetDatabaseNamesCallback final : public EventListener {
DOMStringList* database_names_list = request_result->DomStringList();
std::unique_ptr<protocol::Array<String>> database_names =
protocol::Array<String>::create();
- for (size_t i = 0; i < database_names_list->length(); ++i)
+ for (uint32_t i = 0; i < database_names_list->length(); ++i)
database_names->addItem(database_names_list->item(i));
request_callback_->sendSuccess(std::move(database_names));
}
@@ -401,7 +401,7 @@ std::unique_ptr<KeyPath> KeyPathFromIDBKeyPath(const IDBKeyPath& idb_key_path) {
std::unique_ptr<protocol::Array<String>> array =
protocol::Array<String>::create();
const Vector<String>& string_array = idb_key_path.Array();
- for (size_t i = 0; i < string_array.size(); ++i)
+ for (wtf_size_t i = 0; i < string_array.size(); ++i)
array->addItem(string_array[i]);
key_path->setArray(std::move(array));
break;
@@ -463,7 +463,7 @@ class DatabaseLoader final
std::unique_ptr<DatabaseWithObjectStores> result =
DatabaseWithObjectStores::create()
.setName(idb_database->name())
- .setVersion(idb_database->version())
+ .setVersion(static_cast<int>(idb_database->version()))
.setObjectStores(std::move(object_stores))
.build();
@@ -608,7 +608,7 @@ class OpenCursorCallback final : public EventListener {
return;
}
- Document* document = ToDocument(ExecutionContext::From(script_state_));
+ Document* document = To<Document>(ExecutionContext::From(script_state_));
if (!document)
return;
ScriptState::Scope scope(script_state_);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
index 0aac12d21d1..a7325498632 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
@@ -84,7 +84,7 @@ class MockWebIDBDatabase : public testing::StrictMock<WebIDBDatabase> {
bool key_only,
WebIDBCallbacks*));
- MOCK_METHOD9(Put,
+ MOCK_METHOD8(Put,
void(long long transaction_id,
long long object_store_id,
const WebData& value,
@@ -92,15 +92,13 @@ class MockWebIDBDatabase : public testing::StrictMock<WebIDBDatabase> {
WebIDBKeyView primary_key,
WebIDBPutMode,
WebIDBCallbacks*,
- const WebVector<long long>& index_ids,
- const WebVector<WebIndexKeys>));
+ const WebVector<WebIDBIndexKeys>&));
- MOCK_METHOD5(SetIndexKeys,
+ MOCK_METHOD4(SetIndexKeys,
void(long long transaction_id,
long long object_store_id,
WebIDBKeyView primary_key,
- const WebVector<long long>& index_ids,
- const WebVector<WebIndexKeys>&));
+ const WebVector<WebIDBIndexKeys>&));
MOCK_METHOD3(SetIndexesReady,
void(long long transaction_id,
long long object_store_id,
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
index bebb7e661d8..fe63972adb0 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_value.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
using blink::WebIDBCursor;
using blink::WebIDBDatabase;
@@ -154,7 +155,7 @@ void WebIDBCallbacksImpl::OnSuccess(WebVector<WebIDBValue> values) {
probe::AsyncTask async_task(request_->GetExecutionContext(), this, "success");
Vector<std::unique_ptr<IDBValue>> idb_values;
- idb_values.ReserveInitialCapacity(values.size());
+ idb_values.ReserveInitialCapacity(SafeCast<wtf_size_t>(values.size()));
for (WebIDBValue& value : values) {
std::unique_ptr<IDBValue> idb_value = value.ReleaseIdbValue();
idb_value->SetIsolate(request_->GetIsolate());
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
index d332924c37b..d6980c28019 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h
@@ -23,7 +23,7 @@ class KeyboardLayoutMap final : public ScriptWrappable,
const HashMap<String, String>& Map() const { return layout_map_; }
// IDL attributes / methods
- size_t size() const { return layout_map_.size(); }
+ uint32_t size() const { return layout_map_.size(); }
void Trace(blink::Visitor* visitor) override {
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
index 503294aafe3..93c78e5b9c5 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -43,7 +43,7 @@ double ComputeFrameRate(const String& fps_str) {
if (std::isfinite(result))
return result > 0 ? result : std::numeric_limits<double>::quiet_NaN();
- size_t slash_position = fps_str.find('/');
+ wtf_size_t slash_position = fps_str.find('/');
if (slash_position == kNotFound)
return std::numeric_limits<double>::quiet_NaN();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
index f15b852a55a..5c8e0de3a8a 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
@@ -7,6 +7,8 @@ import("//tools/grit/grit_rule.gni")
blink_modules_sources("media_controls") {
sources = [
+ "elements/media_control_animated_arrow_container_element.cc",
+ "elements/media_control_animated_arrow_container_element.h",
"elements/media_control_animation_event_listener.cc",
"elements/media_control_animation_event_listener.h",
"elements/media_control_button_panel_element.cc",
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc
new file mode 100644
index 00000000000..0848f2d8cce
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc
@@ -0,0 +1,124 @@
+// 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 "third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h"
+
+#include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/html/html_style_element.h"
+#include "third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h"
+
+namespace blink {
+
+MediaControlAnimatedArrowContainerElement::AnimatedArrow::AnimatedArrow(
+ const AtomicString& id,
+ Document& document)
+ : HTMLDivElement(document) {
+ setAttribute("id", id);
+}
+
+void MediaControlAnimatedArrowContainerElement::AnimatedArrow::HideInternal() {
+ DCHECK(!hidden_);
+ svg_container_->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ hidden_ = true;
+}
+
+void MediaControlAnimatedArrowContainerElement::AnimatedArrow::ShowInternal() {
+ DCHECK(hidden_);
+ hidden_ = false;
+
+ if (svg_container_) {
+ svg_container_->RemoveInlineStyleProperty(CSSPropertyDisplay);
+ return;
+ }
+
+ SetInnerHTMLFromString(MediaControlsResourceLoader::GetJumpSVGImage());
+
+ last_arrow_ = getElementById("arrow-3");
+ svg_container_ = getElementById("jump");
+
+ event_listener_ = new MediaControlAnimationEventListener(this);
+}
+
+void MediaControlAnimatedArrowContainerElement::AnimatedArrow::
+ OnAnimationIteration() {
+ counter_--;
+
+ if (counter_ == 0)
+ HideInternal();
+}
+
+void MediaControlAnimatedArrowContainerElement::AnimatedArrow::Show() {
+ if (hidden_)
+ ShowInternal();
+
+ counter_++;
+}
+
+Element& MediaControlAnimatedArrowContainerElement::AnimatedArrow::
+ WatchedAnimationElement() const {
+ return *last_arrow_;
+}
+
+void MediaControlAnimatedArrowContainerElement::AnimatedArrow::Trace(
+ Visitor* visitor) {
+ MediaControlAnimationEventListener::Observer::Trace(visitor);
+ HTMLDivElement::Trace(visitor);
+ visitor->Trace(last_arrow_);
+ visitor->Trace(svg_container_);
+ visitor->Trace(event_listener_);
+}
+
+MediaControlAnimatedArrowContainerElement::
+ MediaControlAnimatedArrowContainerElement(MediaControlsImpl& media_controls)
+ : MediaControlDivElement(media_controls, kMediaAnimatedArrowContainer),
+ left_jump_arrow_(nullptr),
+ right_jump_arrow_(nullptr) {
+ EnsureUserAgentShadowRoot();
+ SetShadowPseudoId(
+ AtomicString("-internal-media-controls-animated-arrow-container"));
+}
+
+void MediaControlAnimatedArrowContainerElement::ShowArrowAnimation(
+ MediaControlAnimatedArrowContainerElement::ArrowDirection direction) {
+ // Load the arrow icons and associate CSS the first time we jump.
+ if (!left_jump_arrow_) {
+ DCHECK(!right_jump_arrow_);
+ ShadowRoot* shadow_root = GetShadowRoot();
+
+ // This stylesheet element and will contain rules that are specific to the
+ // jump arrows. The shadow DOM protects these rules from the parent DOM
+ // from bleeding across the shadow DOM boundary.
+ auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags());
+ style->setTextContent(
+ MediaControlsResourceLoader::GetAnimatedArrowStyleSheet());
+ shadow_root->ParserAppendChild(style);
+
+ left_jump_arrow_ =
+ new MediaControlAnimatedArrowContainerElement::AnimatedArrow(
+ "left-arrow", GetDocument());
+ shadow_root->ParserAppendChild(left_jump_arrow_);
+
+ right_jump_arrow_ =
+ new MediaControlAnimatedArrowContainerElement::AnimatedArrow(
+ "right-arrow", GetDocument());
+ shadow_root->ParserAppendChild(right_jump_arrow_);
+ }
+
+ DCHECK(left_jump_arrow_ && right_jump_arrow_);
+
+ if (direction ==
+ MediaControlAnimatedArrowContainerElement::ArrowDirection::kLeft) {
+ left_jump_arrow_->Show();
+ } else {
+ right_jump_arrow_->Show();
+ }
+}
+
+void MediaControlAnimatedArrowContainerElement::Trace(blink::Visitor* visitor) {
+ MediaControlDivElement::Trace(visitor);
+ visitor->Trace(left_jump_arrow_);
+ visitor->Trace(right_jump_arrow_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h
new file mode 100644
index 00000000000..ea60c72ed80
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ANIMATED_ARROW_CONTAINER_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ANIMATED_ARROW_CONTAINER_ELEMENT_H_
+
+#include "third_party/blink/renderer/core/html/html_div_element.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace WTF {
+class AtomicString;
+}
+
+namespace blink {
+
+class MediaControlsImpl;
+
+class MODULES_EXPORT MediaControlAnimatedArrowContainerElement final
+ : public MediaControlDivElement {
+ public:
+ enum class ArrowDirection { kLeft, kRight };
+
+ explicit MediaControlAnimatedArrowContainerElement(MediaControlsImpl&);
+
+ void ShowArrowAnimation(ArrowDirection);
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ friend class MediaControlAnimatedArrowContainerElementTest;
+
+ // This class is responible for displaying the arrow animation when a jump is
+ // triggered by the user.
+ class MODULES_EXPORT AnimatedArrow final
+ : public HTMLDivElement,
+ public MediaControlAnimationEventListener::Observer {
+ USING_GARBAGE_COLLECTED_MIXIN(AnimatedArrow);
+
+ public:
+ AnimatedArrow(const AtomicString& id, Document& document);
+
+ // MediaControlAnimationEventListener::Observer overrides
+ void OnAnimationIteration() override;
+ void OnAnimationEnd() override{};
+ Element& WatchedAnimationElement() const override;
+
+ // Shows the animated arrows for a single animation iteration. If the
+ // arrows are already shown it will show them for another animation
+ // iteration.
+ void Show();
+
+ void Trace(Visitor*) override;
+
+ private:
+ void HideInternal();
+ void ShowInternal();
+
+ int counter_ = 0;
+ bool hidden_ = true;
+
+ Member<Element> last_arrow_;
+ Member<Element> svg_container_;
+ Member<MediaControlAnimationEventListener> event_listener_;
+ };
+
+ Member<AnimatedArrow> left_jump_arrow_;
+ Member<AnimatedArrow> right_jump_arrow_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ANIMATED_ARROW_CONTAINER_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element_test.cc
new file mode 100644
index 00000000000..584e6c168f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element_test.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 "third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/css_property_value_set.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+
+namespace blink {
+
+class MediaControlAnimatedArrowContainerElementTest : public PageTestBase {
+ public:
+ void SetUp() final {
+ // Create page and instance of AnimatedArrow to run tests on.
+ PageTestBase::SetUp();
+ arrow_element_ =
+ new MediaControlAnimatedArrowContainerElement::AnimatedArrow(
+ "test", GetDocument());
+ GetDocument().body()->AppendChild(arrow_element_);
+ }
+
+ protected:
+ void ExpectNotPresent() { EXPECT_FALSE(SVGElementIsPresent()); }
+
+ void ExpectPresentAndShown() {
+ EXPECT_TRUE(SVGElementIsPresent());
+ EXPECT_FALSE(SVGElementHasDisplayValue());
+ }
+
+ void ExpectPresentAndHidden() {
+ EXPECT_TRUE(SVGElementIsPresent());
+ EXPECT_TRUE(SVGElementHasDisplayValue());
+ }
+
+ void SimulateShow() { arrow_element_->Show(); }
+
+ void SimulateAnimationIteration() {
+ Event* event = Event::Create(EventTypeNames::animationiteration);
+ GetElementById("arrow-3")->DispatchEvent(*event);
+ }
+
+ private:
+ bool SVGElementHasDisplayValue() {
+ return GetElementById("jump")->InlineStyle()->HasProperty(
+ CSSPropertyDisplay);
+ }
+
+ bool SVGElementIsPresent() { return GetElementById("jump"); }
+
+ Element* GetElementById(const AtomicString& id) {
+ return GetDocument().body()->getElementById(id);
+ }
+
+ Persistent<MediaControlAnimatedArrowContainerElement::AnimatedArrow>
+ arrow_element_;
+};
+
+TEST_F(MediaControlAnimatedArrowContainerElementTest, ShowIncrementsCounter) {
+ ExpectNotPresent();
+
+ // Start a new show.
+ SimulateShow();
+ ExpectPresentAndShown();
+
+ // Increment the counter and finish the first show.
+ SimulateShow();
+ SimulateAnimationIteration();
+ ExpectPresentAndShown();
+
+ // Finish the second show.
+ SimulateAnimationIteration();
+ ExpectPresentAndHidden();
+
+ // Start a new show.
+ SimulateShow();
+ ExpectPresentAndShown();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
index cf3cd3b40ae..6f9fd45dd93 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
@@ -63,7 +63,7 @@ class MediaControlDisplayCutoutFullscreenButtonElementTest
void SimulateEnterFullscreen() {
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(*video_);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
index 50c19e07bc6..a240eac3b84 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc
@@ -77,7 +77,7 @@ void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) {
UserMetricsAction("Media.Controls.Download"));
ResourceRequest request(url);
request.SetSuggestedFilename(MediaElement().title());
- request.SetRequestContext(WebURLRequest::kRequestContextDownload);
+ request.SetRequestContext(mojom::RequestContextType::DOWNLOAD);
request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url()));
GetDocument().GetFrame()->Client()->DownloadURL(
request, DownloadCrossOriginRedirects::kFollow);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
index d5a73cc191b..06df6aa5204 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
@@ -39,6 +39,7 @@ enum MediaControlElementType {
kMediaEnterPictureInPictureButton,
kMediaExitPictureInPictureButton,
kMediaDisplayCutoutFullscreenButton,
+ kMediaAnimatedArrowContainer,
};
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_TYPE_H_
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
index 088518dbaba..7a6b6ac02f8 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
@@ -128,4 +128,14 @@ void MediaControlElementsHelper::NotifyMediaControlAccessibleFocus(
->OnAccessibleFocus();
}
+void MediaControlElementsHelper::NotifyMediaControlAccessibleBlur(
+ Element* element) {
+ const HTMLMediaElement* media_element = ToParentMediaElement(element);
+ if (!media_element || !media_element->GetMediaControls())
+ return;
+
+ static_cast<MediaControlsImpl*>(media_element->GetMediaControls())
+ ->OnAccessibleBlur();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
index adc67d95da1..0e39ac3550e 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
@@ -64,6 +64,7 @@ class MediaControlElementsHelper final {
// Utility function that notifies the media controls in which the element is
// that it was focused by an accessibility tool.
static void NotifyMediaControlAccessibleFocus(Element*);
+ static void NotifyMediaControlAccessibleBlur(Element*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
index 34f2affb6ad..da173711dda 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
@@ -64,6 +64,18 @@ void MediaControlMuteButtonElement::DefaultEventHandler(Event& event) {
event.SetDefaultHandled();
}
+ if (!IsOverflowElement()) {
+ if (event.type() == EventTypeNames::mouseover ||
+ event.type() == EventTypeNames::focus) {
+ GetMediaControls().OpenVolumeSliderIfNecessary();
+ }
+
+ if (event.type() == EventTypeNames::mouseout ||
+ event.type() == EventTypeNames::blur) {
+ GetMediaControls().CloseVolumeSliderIfNecessary();
+ }
+ }
+
MediaControlInputElement::DefaultEventHandler(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
index 485796cea4b..aa454a87048 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
@@ -5,44 +5,21 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/events/mouse_event.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_source.h"
#include "third_party/blink/renderer/core/input_type_names.h"
-#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
-#include "third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/time.h"
namespace {
// The size of the inner circle button in pixels.
constexpr int kInnerButtonSize = 56;
-// The touch padding of the inner circle button in pixels.
-constexpr int kInnerButtonTouchPaddingSize = 20;
-
-// Check if a point is based within the boundary of a DOMRect with a margin.
-bool IsPointInRect(blink::DOMRect& rect, int margin, int x, int y) {
- return ((x >= (rect.left() - margin)) && (x <= (rect.right() + margin)) &&
- (y >= (rect.top() - margin)) && (y <= (rect.bottom() + margin)));
-}
-
-// The delay between two taps to be recognized as a double tap gesture.
-constexpr WTF::TimeDelta kDoubleTapDelay = TimeDelta::FromMilliseconds(300);
-
-// The number of seconds to jump when double tapping.
-constexpr int kNumberOfSecondsToJump = 10;
-
// The CSS class to add to hide the element.
const char kHiddenClassName[] = "hidden";
@@ -50,66 +27,6 @@ const char kHiddenClassName[] = "hidden";
namespace blink {
-MediaControlOverlayPlayButtonElement::AnimatedArrow::AnimatedArrow(
- const AtomicString& id,
- Document& document)
- : HTMLDivElement(document) {
- setAttribute("id", id);
-}
-
-void MediaControlOverlayPlayButtonElement::AnimatedArrow::HideInternal() {
- DCHECK(!hidden_);
- svg_container_->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
- hidden_ = true;
-}
-
-void MediaControlOverlayPlayButtonElement::AnimatedArrow::ShowInternal() {
- DCHECK(hidden_);
- hidden_ = false;
-
- if (svg_container_) {
- svg_container_->RemoveInlineStyleProperty(CSSPropertyDisplay);
- return;
- }
-
- SetInnerHTMLFromString(MediaControlsResourceLoader::GetJumpSVGImage());
-
- last_arrow_ = getElementById("arrow-3");
- svg_container_ = getElementById("jump");
-
- event_listener_ = new MediaControlAnimationEventListener(this);
-}
-
-void MediaControlOverlayPlayButtonElement::AnimatedArrow::
- OnAnimationIteration() {
- counter_--;
-
- if (counter_ == 0)
- HideInternal();
-}
-
-void MediaControlOverlayPlayButtonElement::AnimatedArrow::Show() {
- if (hidden_)
- ShowInternal();
-
- counter_++;
-}
-
-Element&
-MediaControlOverlayPlayButtonElement::AnimatedArrow::WatchedAnimationElement()
- const {
- return *last_arrow_;
-}
-
-void MediaControlOverlayPlayButtonElement::AnimatedArrow::Trace(
- Visitor* visitor) {
- MediaControlAnimationEventListener::Observer::Trace(visitor);
- HTMLDivElement::Trace(visitor);
- visitor->Trace(last_arrow_);
- visitor->Trace(svg_container_);
- visitor->Trace(event_listener_);
-}
-
// The DOM structure looks like:
//
// MediaControlOverlayPlayButtonElement
@@ -120,12 +37,7 @@ void MediaControlOverlayPlayButtonElement::AnimatedArrow::Trace(
MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(
MediaControlsImpl& media_controls)
: MediaControlInputElement(media_controls, kMediaPlayButton),
- tap_timer_(GetDocument().GetTaskRunner(TaskType::kMediaElementEvent),
- this,
- &MediaControlOverlayPlayButtonElement::TapTimerFired),
- internal_button_(nullptr),
- left_jump_arrow_(nullptr),
- right_jump_arrow_(nullptr) {
+ internal_button_(nullptr) {
EnsureUserAgentShadowRoot();
setType(InputTypeNames::button);
SetShadowPseudoId(AtomicString("-webkit-media-controls-overlay-play-button"));
@@ -179,146 +91,17 @@ void MediaControlOverlayPlayButtonElement::MaybePlayPause() {
UpdateDisplayType();
}
-void MediaControlOverlayPlayButtonElement::MaybeJump(int seconds) {
- // Load the arrow icons and associate CSS the first time we jump.
- if (!left_jump_arrow_) {
- DCHECK(!right_jump_arrow_);
- ShadowRoot* shadow_root = GetShadowRoot();
-
- // This stylesheet element and will contain rules that are specific to the
- // jump arrows. The shadow DOM protects these rules from the parent DOM
- // from bleeding across the shadow DOM boundary.
- auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags());
- style->setTextContent(
- MediaControlsResourceLoader::GetOverlayPlayStyleSheet());
- shadow_root->ParserAppendChild(style);
-
- // Insert the left jump arrow to the left of the play button.
- left_jump_arrow_ = new MediaControlOverlayPlayButtonElement::AnimatedArrow(
- "left-arrow", GetDocument());
- shadow_root->ParserInsertBefore(left_jump_arrow_,
- *shadow_root->firstChild());
-
- // Insert the right jump arrow to the right of the play button.
- right_jump_arrow_ = new MediaControlOverlayPlayButtonElement::AnimatedArrow(
- "right-arrow", GetDocument());
- shadow_root->ParserAppendChild(right_jump_arrow_);
- }
-
- DCHECK(left_jump_arrow_ && right_jump_arrow_);
- double new_time = std::max(0.0, MediaElement().currentTime() + seconds);
- new_time = std::min(new_time, MediaElement().duration());
- MediaElement().setCurrentTime(new_time);
-
- if (seconds > 0)
- right_jump_arrow_->Show();
- else
- left_jump_arrow_->Show();
-}
-
void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event& event) {
- if (ShouldCausePlayPause(event)) {
+ if (event.type() == EventTypeNames::click) {
event.SetDefaultHandled();
MaybePlayPause();
- } else if (event.type() == EventTypeNames::click) {
- event.SetDefaultHandled();
-
- DCHECK(event.IsMouseEvent());
- auto& mouse_event = ToMouseEvent(event);
- DCHECK(mouse_event.HasPosition());
-
- if (!tap_timer_.IsActive()) {
- // If there was not a previous touch and this was outside of the button
- // then we should toggle visibility with a small unnoticeable delay in
- // case their is a second tap.
- if (tap_timer_.IsActive())
- return;
- tap_was_touch_event_ = MediaControlsImpl::IsTouchEvent(&event);
- tap_timer_.StartOneShot(kDoubleTapDelay, FROM_HERE);
- } else {
- // Cancel the play pause event.
- tap_timer_.Stop();
-
- // If both taps were touch events, then jump.
- if (tap_was_touch_event_.value() &&
- MediaControlsImpl::IsTouchEvent(&event)) {
- // Jump forwards or backwards based on the position of the tap.
- WebSize element_size =
- MediaControlElementsHelper::GetSizeOrDefault(*this, WebSize(0, 0));
-
- if (mouse_event.clientX() >= element_size.width / 2) {
- MaybeJump(kNumberOfSecondsToJump);
- } else {
- MaybeJump(kNumberOfSecondsToJump * -1);
- }
- } else {
- if (GetMediaControls().IsFullscreenEnabled()) {
- // Enter or exit fullscreen.
- if (MediaElement().IsFullscreen())
- GetMediaControls().ExitFullscreen();
- else
- GetMediaControls().EnterFullscreen();
- }
- }
-
- tap_was_touch_event_.reset();
- }
}
MediaControlInputElement::DefaultEventHandler(event);
}
bool MediaControlOverlayPlayButtonElement::KeepEventInNode(
const Event& event) const {
- // We only care about user interaction events.
- if (!MediaControlElementsHelper::IsUserInteractionEvent(event))
- return false;
-
- // For mouse events, only keep in node if they're on the internal button.
- if (event.IsMouseEvent() && MediaControlsImpl::IsModern())
- return IsMouseEventOnInternalButton(ToMouseEvent(event));
-
- return true;
-}
-
-bool MediaControlOverlayPlayButtonElement::ShouldCausePlayPause(
- const Event& event) const {
- // Only click events cause a play/pause.
- if (event.type() != EventTypeNames::click)
- return false;
-
- // Double tap to navigate should only be available on modern controls.
- if (!MediaControlsImpl::IsModern() || !event.IsMouseEvent())
- return true;
-
- // TODO(beccahughes): Move to PointerEvent.
- return IsMouseEventOnInternalButton(ToMouseEvent(event));
-}
-
-bool MediaControlOverlayPlayButtonElement::IsMouseEventOnInternalButton(
- const MouseEvent& mouse_event) const {
- // If we don't have the necessary pieces to calculate whether the event is
- // within the bounds of the button, default to yes.
- if (!mouse_event.HasPosition() || !isConnected() ||
- !GetDocument().GetLayoutView() || !MediaElement().ShouldShowControls()) {
- return true;
- }
-
- // If there is no layout view, default to yes.
- if (!GetDocument().GetLayoutView())
- return true;
-
- // Find the zoom-adjusted internal button bounding box.
- DOMRect* box = internal_button_->getBoundingClientRect();
- float zoom = ComputedStyleRef().EffectiveZoom() /
- GetDocument().GetLayoutView()->ZoomFactor();
- box->setX(box->x() * zoom);
- box->setY(box->y() * zoom);
- box->setWidth(box->width() * zoom);
- box->setHeight(box->height() * zoom);
-
- // Check the button and a margin around it.
- return IsPointInRect(*box, kInnerButtonTouchPaddingSize,
- mouse_event.clientX(), mouse_event.clientY());
+ return MediaControlElementsHelper::IsUserInteractionEvent(event);
}
WebSize MediaControlOverlayPlayButtonElement::GetSizeOrDefault() const {
@@ -336,17 +119,9 @@ void MediaControlOverlayPlayButtonElement::SetIsDisplayed(bool displayed) {
displayed_ = displayed;
}
-void MediaControlOverlayPlayButtonElement::TapTimerFired(TimerBase*) {
- if (tap_was_touch_event_.value())
- GetMediaControls().MaybeToggleControlsFromTap();
- tap_was_touch_event_.reset();
-}
-
void MediaControlOverlayPlayButtonElement::Trace(blink::Visitor* visitor) {
MediaControlInputElement::Trace(visitor);
visitor->Trace(internal_button_);
- visitor->Trace(left_jump_arrow_);
- visitor->Trace(right_jump_arrow_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
index d2eec864f5b..e7ef4575925 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h
@@ -6,20 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_OVERLAY_PLAY_BUTTON_ELEMENT_H_
#include "third_party/blink/renderer/core/html/html_div_element.h"
-#include "third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/timer.h"
-
-namespace WTF {
-class AtomicString;
-}
namespace blink {
class Event;
class MediaControlsImpl;
-class MouseEvent;
class MODULES_EXPORT MediaControlOverlayPlayButtonElement final
: public MediaControlInputElement {
@@ -41,58 +34,12 @@ class MODULES_EXPORT MediaControlOverlayPlayButtonElement final
const char* GetNameForHistograms() const override;
private:
- friend class MediaControlOverlayPlayButtonElementTest;
-
- // This class is responible for displaying the arrow animation when a jump is
- // triggered by the user.
- class MODULES_EXPORT AnimatedArrow final
- : public HTMLDivElement,
- public MediaControlAnimationEventListener::Observer {
- USING_GARBAGE_COLLECTED_MIXIN(AnimatedArrow);
-
- public:
- AnimatedArrow(const AtomicString& id, Document& document);
-
- // MediaControlAnimationEventListener::Observer overrides
- void OnAnimationIteration() override;
- void OnAnimationEnd() override{};
- Element& WatchedAnimationElement() const override;
-
- // Shows the animated arrows for a single animation iteration. If the
- // arrows are already shown it will show them for another animation
- // iteration.
- void Show();
-
- void Trace(Visitor*) override;
-
- private:
- void HideInternal();
- void ShowInternal();
-
- int counter_ = 0;
- bool hidden_ = true;
-
- Member<Element> last_arrow_;
- Member<Element> svg_container_;
- Member<MediaControlAnimationEventListener> event_listener_;
- };
-
- void TapTimerFired(TimerBase*);
-
void DefaultEventHandler(Event&) override;
bool KeepEventInNode(const Event&) const override;
- bool ShouldCausePlayPause(const Event&) const;
- bool IsMouseEventOnInternalButton(const MouseEvent&) const;
void MaybePlayPause();
- void MaybeJump(int);
-
- TaskRunnerTimer<MediaControlOverlayPlayButtonElement> tap_timer_;
- base::Optional<bool> tap_was_touch_event_;
Member<HTMLDivElement> internal_button_;
- Member<AnimatedArrow> left_jump_arrow_;
- Member<AnimatedArrow> right_jump_arrow_;
bool displayed_ = true;
};
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
deleted file mode 100644
index a6cf60699f9..00000000000
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
+++ /dev/null
@@ -1,130 +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 "third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/css/css_property_value_set.h"
-#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/event_type_names.h"
-#include "third_party/blink/renderer/core/events/mouse_event.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/html/html_html_element.h"
-#include "third_party/blink/renderer/core/html/media/html_video_element.h"
-#include "third_party/blink/renderer/core/testing/page_test_base.h"
-#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-
-namespace blink {
-
-class MediaControlOverlayPlayButtonElementTest : public PageTestBase {
- public:
- void SetUp() final {
- // Create page and instance of AnimatedArrow to run tests on.
- PageTestBase::SetUp();
- arrow_element_ = new MediaControlOverlayPlayButtonElement::AnimatedArrow(
- "test", GetDocument());
- GetDocument().body()->AppendChild(arrow_element_);
- }
-
- protected:
- void ExpectNotPresent() { EXPECT_FALSE(SVGElementIsPresent()); }
-
- void ExpectPresentAndShown() {
- EXPECT_TRUE(SVGElementIsPresent());
- EXPECT_FALSE(SVGElementHasDisplayValue());
- }
-
- void ExpectPresentAndHidden() {
- EXPECT_TRUE(SVGElementIsPresent());
- EXPECT_TRUE(SVGElementHasDisplayValue());
- }
-
- void SimulateShow() { arrow_element_->Show(); }
-
- void SimulateAnimationIteration() {
- Event* event = Event::Create(EventTypeNames::animationiteration);
- GetElementById("arrow-3")->DispatchEvent(*event);
- }
-
- Document& CreateTestDocumentWithBody() {
- Document* document = Document::CreateForTest();
- HTMLHtmlElement* html = HTMLHtmlElement::Create(*document);
- document->AppendChild(html);
- document->documentElement()->SetInnerHTMLFromString("<body></body>");
- return *document;
- }
-
- void CreateTestOverlayPlayButton(Document& test_document) {
- // Create a video element so that a MediaControlsImpl is created.
- HTMLVideoElement* media_element = HTMLVideoElement::Create(test_document);
- media_element->SetBooleanAttribute(HTMLNames::controlsAttr, true);
- test_document.body()->AppendChild(media_element);
-
- MediaControlsImpl* media_controls =
- static_cast<MediaControlsImpl*>(media_element->GetMediaControls());
- ASSERT_NE(nullptr, media_controls);
-
- // Create a MediaControlOverlayPlayButtonElement for testing.
- overlay_play_button_ =
- new MediaControlOverlayPlayButtonElement(*media_controls);
- }
-
- void SimulateKeepEventInNode() {
- MouseEventInit mouse_initializer;
- mouse_initializer.setView(GetDocument().domWindow());
- mouse_initializer.setButton(1);
-
- MouseEvent* mouse_event =
- MouseEvent::Create(nullptr, EventTypeNames::click, mouse_initializer);
- overlay_play_button_->KeepEventInNode(*mouse_event);
- }
-
- private:
- bool SVGElementHasDisplayValue() {
- return GetElementById("jump")->InlineStyle()->HasProperty(
- CSSPropertyDisplay);
- }
-
- bool SVGElementIsPresent() { return GetElementById("jump"); }
-
- Element* GetElementById(const AtomicString& id) {
- return GetDocument().body()->getElementById(id);
- }
-
- Persistent<MediaControlOverlayPlayButtonElement> overlay_play_button_;
- Persistent<MediaControlOverlayPlayButtonElement::AnimatedArrow>
- arrow_element_;
-};
-
-TEST_F(MediaControlOverlayPlayButtonElementTest, ShowIncrementsCounter) {
- ExpectNotPresent();
-
- // Start a new show.
- SimulateShow();
- ExpectPresentAndShown();
-
- // Increment the counter and finish the first show.
- SimulateShow();
- SimulateAnimationIteration();
- ExpectPresentAndShown();
-
- // Finish the second show.
- SimulateAnimationIteration();
- ExpectPresentAndHidden();
-
- // Start a new show.
- SimulateShow();
- ExpectPresentAndShown();
-}
-
-TEST_F(MediaControlOverlayPlayButtonElementTest,
- KeepEventInNodeWithoutLayoutViewDoesntCrash) {
- ScopedModernMediaControlsForTest enable_modern_media_controls(true);
- Document& document_without_layout_view = CreateTestDocumentWithBody();
- CreateTestOverlayPlayButton(document_without_layout_view);
- SimulateKeepEventInNode();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
index b4d02b11036..22848fc0ddd 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
@@ -125,7 +125,8 @@ void MediaControlPanelElement::MakeTransparent() {
opaque_ = false;
}
-void MediaControlPanelElement::RemovedFrom(ContainerNode&) {
+void MediaControlPanelElement::RemovedFrom(ContainerNode& insertion_point) {
+ MediaControlDivElement::RemovedFrom(insertion_point);
DetachTransitionEventListener();
}
@@ -134,6 +135,10 @@ void MediaControlPanelElement::Trace(blink::Visitor* visitor) {
visitor->Trace(event_listener_);
}
+bool MediaControlPanelElement::KeepDisplayedForAccessibility() {
+ return keep_displayed_for_accessibility_;
+}
+
void MediaControlPanelElement::SetKeepDisplayedForAccessibility(bool value) {
keep_displayed_for_accessibility_ = value;
}
@@ -168,7 +173,7 @@ void MediaControlPanelElement::DetachTransitionEventListener() {
void MediaControlPanelElement::DefaultEventHandler(Event& event) {
// Suppress the media element activation behavior (toggle play/pause) when
// any part of the control panel is clicked.
- if (event.type() == EventTypeNames::click) {
+ if (event.type() == EventTypeNames::click && !MediaControlsImpl::IsModern()) {
event.SetDefaultHandled();
return;
}
@@ -176,7 +181,8 @@ void MediaControlPanelElement::DefaultEventHandler(Event& event) {
}
bool MediaControlPanelElement::KeepEventInNode(const Event& event) const {
- return !MediaControlsImpl::IsModern() &&
+ return (!MediaControlsImpl::IsModern() ||
+ GetMediaControls().ShouldShowAudioControls()) &&
MediaControlElementsHelper::IsUserInteractionEvent(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
index 301e1a26722..ccb43bbb8fa 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h
@@ -26,6 +26,7 @@ class MODULES_EXPORT MediaControlPanelElement final
void MakeOpaque();
void MakeTransparent();
+ bool KeepDisplayedForAccessibility();
void SetKeepDisplayedForAccessibility(bool);
// Node override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
index d158961a2b5..f44fe39f8cb 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
@@ -49,6 +49,7 @@ class MediaControlPanelElementTest : public PageTestBase {
}
MediaControlPanelElement& GetPanel() { return *panel_element_.Get(); }
+ HTMLMediaElement& GetMediaElement() { return *media_element_.Get(); }
private:
void TriggerEvent(const AtomicString& name) {
@@ -89,4 +90,12 @@ TEST_F(MediaControlPanelElementTest, StateTransitions) {
ExpectPanelIsDisplayed();
}
+TEST_F(MediaControlPanelElementTest, isConnected) {
+ EXPECT_TRUE(
+ GetMediaElement().GetMediaControls()->PanelElement()->isConnected());
+ GetMediaElement().remove();
+ EXPECT_FALSE(
+ GetMediaElement().GetMediaControls()->PanelElement()->isConnected());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
index 03276daaf1d..0cb0d29c3a1 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
@@ -161,6 +162,11 @@ void MediaControlPopupMenuElement::DefaultEventHandler(Event& event) {
MediaControlDivElement::DefaultEventHandler(event);
}
+bool MediaControlPopupMenuElement::KeepEventInNode(const Event& event) const {
+ return MediaControlsImpl::IsModern() &&
+ MediaControlElementsHelper::IsUserInteractionEvent(event);
+}
+
void MediaControlPopupMenuElement::RemovedFrom(ContainerNode& container) {
if (IsWanted())
SetIsWanted(false);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
index 691f301be7d..a538d3ee566 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h
@@ -26,6 +26,7 @@ class MediaControlPopupMenuElement : public MediaControlDivElement {
// Node override.
void DefaultEventHandler(Event&) override;
+ bool KeepEventInNode(const Event&) const override;
void RemovedFrom(ContainerNode&) override;
void Trace(blink::Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
index afc97376393..2ffacc5f603 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -14,12 +15,22 @@
namespace blink {
+namespace {
+
+const char kClosedCSSClass[] = "closed";
+
+} // anonymous namespace
+
MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(
MediaControlsImpl& media_controls)
: MediaControlSliderElement(media_controls, kMediaVolumeSlider) {
setAttribute(HTMLNames::maxAttr, "1");
SetShadowPseudoId(AtomicString("-webkit-media-controls-volume-slider"));
SetVolumeInternal(MediaElement().volume());
+
+ // The slider starts closed in modern media controls.
+ if (MediaControlsImpl::IsModern())
+ CloseSlider();
}
void MediaControlVolumeSliderElement::SetVolume(double volume) {
@@ -30,6 +41,14 @@ void MediaControlVolumeSliderElement::SetVolume(double volume) {
SetVolumeInternal(volume);
}
+void MediaControlVolumeSliderElement::OpenSlider() {
+ classList().Remove(kClosedCSSClass);
+}
+
+void MediaControlVolumeSliderElement::CloseSlider() {
+ classList().Add(kClosedCSSClass);
+}
+
bool MediaControlVolumeSliderElement::WillRespondToMouseMoveEvents() {
if (!isConnected() || !GetDocument().IsActive())
return false;
@@ -75,6 +94,16 @@ void MediaControlVolumeSliderElement::DefaultEventHandler(Event& event) {
MediaElement().setMuted(false);
SetVolumeInternal(volume);
}
+
+ if (event.type() == EventTypeNames::mouseover ||
+ event.type() == EventTypeNames::focus) {
+ GetMediaControls().OpenVolumeSliderIfNecessary();
+ }
+
+ if (event.type() == EventTypeNames::mouseout ||
+ event.type() == EventTypeNames::blur) {
+ GetMediaControls().CloseVolumeSliderIfNecessary();
+ }
}
void MediaControlVolumeSliderElement::SetVolumeInternal(double volume) {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
index 2e9962f5c25..dc37b48d74f 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
@@ -19,6 +19,9 @@ class MediaControlVolumeSliderElement final : public MediaControlSliderElement {
// TODO: who calls this?
void SetVolume(double);
+ void OpenSlider();
+ void CloseSlider();
+
// MediaControlInputElement overrides.
bool WillRespondToMouseMoveEvents() override;
bool WillRespondToMouseClickEvents() override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
index bd53ac69e41..04eb76ab939 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
@@ -55,7 +55,7 @@ class MediaControlsDisplayCutoutDelegateTest : public PageTestBase {
void SimulateEnterFullscreen() {
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(GetVideoElement());
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index fa2415ecb14..43a10f53557 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -29,7 +29,6 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
-#include "third_party/blink/renderer/core/css/css_style_declaration.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
@@ -40,6 +39,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
+#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
@@ -51,6 +51,7 @@
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.h"
@@ -131,14 +132,11 @@ const char kScrubbingMessageCSSClass[] = "scrubbing-message";
const char kTestModeCSSClass[] = "test-mode";
const char kImmersiveModeCSSClass[] = "immersive-mode";
-// The ratio of video width/height to use for play button size.
-constexpr float kSizingSmallOverlayPlayButtonSizeRatio = 0.25;
-constexpr float kSizingMediumOverlayPlayButtonSizeRatio = 0.15;
-constexpr float kSizingLargeOverlayPlayButtonSizeRatio = 0.11;
+// The delay between two taps to be recognized as a double tap gesture.
+constexpr WTF::TimeDelta kDoubleTapDelay = TimeDelta::FromMilliseconds(300);
-// Used for setting overlay play button width CSS variable.
-constexpr double kMinOverlayPlayButtonWidth = 48;
-const char kOverlayPlayButtonWidthCSSVar[] = "--overlay-play-button-width";
+// The number of seconds to jump when double tapping.
+constexpr int kNumberOfSecondsToJump = 10;
bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) {
// Unconditionally allow the user to exit fullscreen if we are in it
@@ -368,6 +366,7 @@ MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& media_element)
media_button_panel_(nullptr),
loading_panel_(nullptr),
picture_in_picture_button_(nullptr),
+ animated_arrow_container_element_(nullptr),
cast_button_(nullptr),
fullscreen_button_(nullptr),
display_cutout_fullscreen_button_(nullptr),
@@ -390,7 +389,11 @@ MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& media_element)
media_element.GetDocument().GetTaskRunner(TaskType::kInternalMedia),
this,
&MediaControlsImpl::ElementSizeChangedTimerFired),
- keep_showing_until_timer_fires_(false) {
+ keep_showing_until_timer_fires_(false),
+ tap_timer_(
+ media_element.GetDocument().GetTaskRunner(TaskType::kInternalMedia),
+ this,
+ &MediaControlsImpl::TapTimerFired) {
// On touch devices, start with the assumption that the user will interact via
// touch events.
Settings* settings = media_element.GetDocument().GetSettings();
@@ -525,8 +528,7 @@ void MediaControlsImpl::InitializeControls() {
overlay_enclosure_ = new MediaControlOverlayEnclosureElement(*this);
- if (RuntimeEnabledFeatures::MediaControlsOverlayPlayButtonEnabled() ||
- IsModern()) {
+ if (RuntimeEnabledFeatures::MediaControlsOverlayPlayButtonEnabled()) {
overlay_play_button_ = new MediaControlOverlayPlayButtonElement(*this);
if (!IsModern())
@@ -560,12 +562,9 @@ void MediaControlsImpl::InitializeControls() {
timeline_ = new MediaControlTimelineElement(*this);
mute_button_ = new MediaControlMuteButtonElement(*this);
- // The volume slider should be shown if we are using the legacy controls.
- if (!IsModern()) {
- volume_slider_ = new MediaControlVolumeSliderElement(*this);
- if (PreferHiddenVolumeControls(GetDocument()))
- volume_slider_->SetIsWanted(false);
- }
+ volume_slider_ = new MediaControlVolumeSliderElement(*this);
+ if (PreferHiddenVolumeControls(GetDocument()))
+ volume_slider_->SetIsWanted(false);
if (RuntimeEnabledFeatures::PictureInPictureEnabled() &&
GetDocument().GetSettings() &&
@@ -640,7 +639,7 @@ void MediaControlsImpl::PopulatePanel() {
if (display_cutout_fullscreen_button_)
panel_->ParserAppendChild(display_cutout_fullscreen_button_);
- panel_->ParserAppendChild(overlay_play_button_);
+ MaybeParserAppendChild(panel_, overlay_play_button_);
panel_->ParserAppendChild(media_button_panel_);
button_panel = media_button_panel_;
}
@@ -656,9 +655,15 @@ void MediaControlsImpl::PopulatePanel() {
panel_->ParserAppendChild(timeline_);
- button_panel->ParserAppendChild(mute_button_);
+ // On modern controls, the volume slider is to the left of the mute button.
+ if (IsModern()) {
+ MaybeParserAppendChild(button_panel, volume_slider_);
+ button_panel->ParserAppendChild(mute_button_);
+ } else {
+ button_panel->ParserAppendChild(mute_button_);
+ MaybeParserAppendChild(button_panel, volume_slider_);
+ }
- MaybeParserAppendChild(button_panel, volume_slider_);
MaybeParserAppendChild(button_panel, picture_in_picture_button_);
button_panel->ParserAppendChild(fullscreen_button_);
@@ -754,18 +759,35 @@ void MediaControlsImpl::UpdateCSSClassFromState() {
// If we are in the "no-source" state we should show the overflow menu on a
// video element.
if (IsModern()) {
+ bool updated = false;
+
if (state == kNoSource) {
- // Check if the overflow menu has the "disabled" attribute set so we avoid
- // unnecessarily resetting it.
+ // Check if the play button or overflow menu has the "disabled" attribute
+ // set so we avoid unnecessarily resetting it.
+ if (!play_button_->hasAttribute(HTMLNames::disabledAttr)) {
+ play_button_->setAttribute(HTMLNames::disabledAttr, "");
+ updated = true;
+ }
+
if (ShouldShowVideoControls() &&
!overflow_menu_->hasAttribute(HTMLNames::disabledAttr)) {
overflow_menu_->setAttribute(HTMLNames::disabledAttr, "");
- UpdateOverflowMenuWanted();
+ updated = true;
+ }
+ } else {
+ if (play_button_->hasAttribute(HTMLNames::disabledAttr)) {
+ play_button_->removeAttribute(HTMLNames::disabledAttr);
+ updated = true;
+ }
+
+ if (overflow_menu_->hasAttribute(HTMLNames::disabledAttr)) {
+ overflow_menu_->removeAttribute(HTMLNames::disabledAttr);
+ updated = true;
}
- } else if (overflow_menu_->hasAttribute(HTMLNames::disabledAttr)) {
- overflow_menu_->removeAttribute(HTMLNames::disabledAttr);
- UpdateOverflowMenuWanted();
}
+
+ if (updated)
+ UpdateOverflowMenuWanted();
}
}
@@ -813,8 +835,7 @@ void MediaControlsImpl::RemovedFrom(ContainerNode& insertion_point) {
HTMLDivElement::RemovedFrom(insertion_point);
- // TODO(mlamouri): we hide show the controls instead of having
- // HTMLMediaElement do it.
+ Hide();
media_event_listener_->Detach();
if (orientation_lock_delegate_)
@@ -1040,6 +1061,10 @@ bool MediaControlsImpl::ShouldHideMediaControls(unsigned behavior_flags) const {
if (download_iph_manager_ && download_iph_manager_->IsShowingInProductHelp())
return false;
+ // Don't hide if we have accessiblity focus.
+ if (panel_->KeepDisplayedForAccessibility())
+ return false;
+
return true;
}
@@ -1246,13 +1271,16 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const {
// room and hide the overlay play button if there is not enough room.
if (ShouldShowVideoControls()) {
// Allocate vertical room for overlay play button if necessary.
- WebSize overlay_play_button_size = overlay_play_button_->GetSizeOrDefault();
- if (controls_size.height >= overlay_play_button_size.height &&
- controls_size.width >= kModernMinWidthForOverlayPlayButton) {
- overlay_play_button_->SetDoesFit(true);
- controls_size.height -= overlay_play_button_size.height;
- } else {
- overlay_play_button_->SetDoesFit(false);
+ if (overlay_play_button_) {
+ WebSize overlay_play_button_size =
+ overlay_play_button_->GetSizeOrDefault();
+ if (controls_size.height >= overlay_play_button_size.height &&
+ controls_size.width >= kModernMinWidthForOverlayPlayButton) {
+ overlay_play_button_->SetDoesFit(true);
+ controls_size.height -= overlay_play_button_size.height;
+ } else {
+ overlay_play_button_->SetDoesFit(false);
+ }
}
controls_size.width -= kModernControlsVideoButtonPadding;
@@ -1269,7 +1297,8 @@ void MediaControlsImpl::UpdateOverflowMenuWanted() const {
}
// If we cannot show the overlay play button, show the normal one.
- play_button_->SetIsWanted(!overlay_play_button_->DoesFit());
+ play_button_->SetIsWanted(!overlay_play_button_ ||
+ !overlay_play_button_->DoesFit());
} else {
controls_size.width -= kModernControlsAudioButtonPadding;
@@ -1360,42 +1389,6 @@ void MediaControlsImpl::UpdateSizingCSSClass() {
SetClass(kMediaControlsSizingLargeCSSClass,
ShouldShowVideoControls() &&
sizing_class == MediaControlsSizingClass::kLarge);
-
- UpdateOverlayPlayButtonWidthCSSVar();
-}
-
-void MediaControlsImpl::UpdateOverlayPlayButtonWidthCSSVar() {
- // The logic for sizing the overlay play button and its use inside the
- // controls is a bit too complex for CSS alone (the sizing is a min of two
- // values maxed with another, and then that needs to be used in calculations
- // for the spinner as well). To work around this, we're using a CSS variable
- // set here and used inside the controls CSS.
- int width = size_.Width();
- int height = size_.Height();
- double minDimension = std::min(width, height);
-
- MediaControlsSizingClass sizing_class = MediaControls::GetSizingClass(width);
- double sizingRatio;
- if (sizing_class == MediaControlsSizingClass::kLarge) {
- sizingRatio = kSizingLargeOverlayPlayButtonSizeRatio;
- } else if (sizing_class == MediaControlsSizingClass::kMedium) {
- sizingRatio = kSizingMediumOverlayPlayButtonSizeRatio;
- } else {
- sizingRatio = kSizingSmallOverlayPlayButtonSizeRatio;
- }
-
- double play_button_width =
- std::max(kMinOverlayPlayButtonWidth, minDimension * sizingRatio);
-
- WTF::String play_button_css_value = WTF::String::Number(play_button_width);
- play_button_css_value.append("px");
-
- if (!overlay_play_button_width_.has_value() ||
- overlay_play_button_width_.value() != play_button_width) {
- overlay_play_button_width_ = play_button_width;
- style()->setProperty(&GetDocument(), kOverlayPlayButtonWidthCSSVar,
- play_button_css_value, "", ASSERT_NO_EXCEPTION);
- }
}
void MediaControlsImpl::MaybeToggleControlsFromTap() {
@@ -1416,16 +1409,33 @@ void MediaControlsImpl::MaybeToggleControlsFromTap() {
}
void MediaControlsImpl::OnAccessibleFocus() {
+ if (panel_->KeepDisplayedForAccessibility())
+ return;
+
panel_->SetKeepDisplayedForAccessibility(true);
if (!MediaElement().ShouldShowControls())
return;
+ OpenVolumeSliderIfNecessary();
+
keep_showing_until_timer_fires_ = true;
StartHideMediaControlsTimer();
MaybeShow();
}
+void MediaControlsImpl::OnAccessibleBlur() {
+ panel_->SetKeepDisplayedForAccessibility(false);
+
+ if (MediaElement().ShouldShowControls())
+ return;
+
+ CloseVolumeSliderIfNecessary();
+
+ keep_showing_until_timer_fires_ = false;
+ ResetHideMediaControlsTimer();
+}
+
void MediaControlsImpl::DefaultEventHandler(Event& event) {
HTMLDivElement::DefaultEventHandler(event);
@@ -1458,6 +1468,9 @@ void MediaControlsImpl::DefaultEventHandler(Event& event) {
HandlePointerEvent(&event);
}
+ if (event.type() == EventTypeNames::click && !is_touch_interaction_)
+ HandleClickEvent(&event);
+
// If the user is interacting with the controls via the keyboard, don't hide
// the controls. This will fire when the user tabs between controls (focusin)
// or when they seek either the timeline or volume sliders (input).
@@ -1470,7 +1483,7 @@ void MediaControlsImpl::DefaultEventHandler(Event& event) {
!IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
const String& key = ToKeyboardEvent(event).key();
if (key == "Enter" || ToKeyboardEvent(event).keyCode() == ' ') {
- if (IsModern()) {
+ if (IsModern() && overlay_play_button_) {
overlay_play_button_->OnMediaKeyboardEvent(&event);
} else {
play_button_->OnMediaKeyboardEvent(&event);
@@ -1482,8 +1495,7 @@ void MediaControlsImpl::DefaultEventHandler(Event& event) {
timeline_->OnMediaKeyboardEvent(&event);
return;
}
- // We don't allow the user to change the volume on modern media controls.
- if (!IsModern() && (key == "ArrowDown" || key == "ArrowUp")) {
+ if (volume_slider_ && (key == "ArrowDown" || key == "ArrowUp")) {
for (int i = 0; i < 5; i++)
volume_slider_->OnMediaKeyboardEvent(&event);
return;
@@ -1515,10 +1527,46 @@ void MediaControlsImpl::HandlePointerEvent(Event* event) {
}
}
+void MediaControlsImpl::HandleClickEvent(Event* event) {
+ if (!IsModern() || ContainsRelatedTarget(event) || !IsFullscreenEnabled())
+ return;
+
+ if (tap_timer_.IsActive()) {
+ tap_timer_.Stop();
+
+ // Toggle fullscreen.
+ if (MediaElement().IsFullscreen())
+ ExitFullscreen();
+ else
+ EnterFullscreen();
+ } else {
+ tap_timer_.StartOneShot(kDoubleTapDelay, FROM_HERE);
+ }
+}
+
void MediaControlsImpl::HandleTouchEvent(Event* event) {
if (IsModern()) {
is_mouse_over_controls_ = false;
is_touch_interaction_ = true;
+
+ if (event->type() == EventTypeNames::click &&
+ !ContainsRelatedTarget(event)) {
+ event->SetDefaultHandled();
+
+ if (tap_timer_.IsActive()) {
+ // Cancel the visibility toggle event.
+ tap_timer_.Stop();
+
+ if (IsOnLeftSide(event)) {
+ MaybeJump(kNumberOfSecondsToJump * -1);
+ } else {
+ MaybeJump(kNumberOfSecondsToJump);
+ }
+ } else {
+ tap_timer_.StartOneShot(kDoubleTapDelay, FROM_HERE);
+ }
+ }
+ return;
}
if (event->type() == EventTypeNames::gesturetap &&
@@ -1536,6 +1584,47 @@ void MediaControlsImpl::HandleTouchEvent(Event* event) {
}
}
+void MediaControlsImpl::EnsureAnimatedArrowContainer() {
+ if (!animated_arrow_container_element_) {
+ animated_arrow_container_element_ =
+ new MediaControlAnimatedArrowContainerElement(*this);
+ ParserAppendChild(animated_arrow_container_element_);
+ }
+}
+
+void MediaControlsImpl::MaybeJump(int seconds) {
+ // Update the current time.
+ double new_time = std::max(0.0, MediaElement().currentTime() + seconds);
+ new_time = std::min(new_time, MediaElement().duration());
+ MediaElement().setCurrentTime(new_time);
+
+ // Show the arrow animation.
+ EnsureAnimatedArrowContainer();
+ MediaControlAnimatedArrowContainerElement::ArrowDirection direction =
+ (seconds > 0)
+ ? MediaControlAnimatedArrowContainerElement::ArrowDirection::kRight
+ : MediaControlAnimatedArrowContainerElement::ArrowDirection::kLeft;
+ animated_arrow_container_element_->ShowArrowAnimation(direction);
+}
+
+bool MediaControlsImpl::IsOnLeftSide(Event* event) {
+ if (!event->IsMouseEvent())
+ return false;
+
+ MouseEvent* mouse_event = ToMouseEvent(event);
+ if (!mouse_event->HasPosition())
+ return false;
+
+ DOMRect* rect = getBoundingClientRect();
+ double middle = rect->x() + (rect->width() / 2);
+ return mouse_event->clientX() < middle;
+}
+
+void MediaControlsImpl::TapTimerFired(TimerBase*) {
+ if (is_touch_interaction_)
+ MaybeToggleControlsFromTap();
+}
+
void MediaControlsImpl::HideMediaControlsTimerFired(TimerBase*) {
unsigned behavior_flags =
hide_timer_behavior_flags_ | kIgnoreFocus | kIgnoreVideoHover;
@@ -1591,7 +1680,6 @@ void MediaControlsImpl::OnVolumeChange() {
// Update visibility of volume controls.
// TODO(mlamouri): it should not be part of the volumechange handling because
// it is using audio availability as input.
- BatchedControlUpdate batch(this);
if (volume_slider_) {
volume_slider_->SetVolume(MediaElement().muted() ? 0
: MediaElement().volume());
@@ -1607,6 +1695,12 @@ void MediaControlsImpl::OnVolumeChange() {
mute_button_->SetIsWanted(MediaElement().HasAudio());
mute_button_->removeAttribute(HTMLNames::disabledAttr);
}
+
+ // On modern media controls, if the volume slider is being used we don't want
+ // to update controls visiblity, since this can shift the position of the
+ // volume slider and make it unusable.
+ if (!IsModern() || !volume_slider_ || !volume_slider_->IsHovered())
+ BatchedControlUpdate batch(this);
}
void MediaControlsImpl::OnFocusIn() {
@@ -2021,6 +2115,30 @@ void MediaControlsImpl::StartHideMediaControlsIfNecessary() {
StartHideMediaControlsTimer();
}
+void MediaControlsImpl::OpenVolumeSliderIfNecessary() {
+ if (ShouldOpenVolumeSlider())
+ volume_slider_->OpenSlider();
+}
+
+void MediaControlsImpl::CloseVolumeSliderIfNecessary() {
+ if (ShouldCloseVolumeSlider())
+ volume_slider_->CloseSlider();
+}
+
+bool MediaControlsImpl::ShouldOpenVolumeSlider() const {
+ if (!volume_slider_ || !IsModern())
+ return false;
+
+ return !PreferHiddenVolumeControls(GetDocument());
+}
+
+bool MediaControlsImpl::ShouldCloseVolumeSlider() const {
+ if (!volume_slider_ || !IsModern())
+ return false;
+
+ return !(volume_slider_->IsHovered() || mute_button_->IsHovered());
+}
+
const MediaControlDownloadButtonElement& MediaControlsImpl::DownloadButton()
const {
return *download_button_;
@@ -2069,6 +2187,7 @@ void MediaControlsImpl::Trace(blink::Visitor* visitor) {
visitor->Trace(mute_button_);
visitor->Trace(volume_slider_);
visitor->Trace(picture_in_picture_button_);
+ visitor->Trace(animated_arrow_container_element_);
visitor->Trace(toggle_closed_captions_button_);
visitor->Trace(fullscreen_button_);
visitor->Trace(download_button_);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
index e87c133017e..53e85b7e9e4 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -42,6 +42,7 @@ class MediaControlsDisplayCutoutDelegate;
class MediaControlsOrientationLockDelegate;
class MediaControlsRotateToFullscreenDelegate;
class MediaControlsWindowEventListener;
+class MediaControlAnimatedArrowContainerElement;
class MediaControlButtonPanelElement;
class MediaControlCastButtonElement;
class MediaControlCurrentTimeDisplayElement;
@@ -136,6 +137,9 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void ToggleOverflowMenu();
bool OverflowMenuVisible();
+ void OpenVolumeSliderIfNecessary();
+ void CloseVolumeSliderIfNecessary();
+
void ShowOverlayCastButtonIfNeeded();
// Methods call by the scrubber.
@@ -189,6 +193,10 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
// accessibility tool. This is meant to be replaced by AOM when the event will
// be exposed to the platform.
void OnAccessibleFocus();
+ void OnAccessibleBlur();
+
+ // Returns true/false based on which set of controls to display.
+ bool ShouldShowAudioControls() const;
private:
// MediaControlsMediaEventListener is a component that is listening to events
@@ -262,6 +270,9 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void HideCursor();
void ShowCursor();
+ bool ShouldOpenVolumeSlider() const;
+ bool ShouldCloseVolumeSlider() const;
+
void ElementSizeChangedTimerFired(TimerBase*);
// Hide elements that don't fit, and show those things that we want which
@@ -272,7 +283,6 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void UpdateOverflowMenuWanted() const;
void UpdateScrubbingMessageFits() const;
void UpdateSizingCSSClass();
- void UpdateOverlayPlayButtonWidthCSSVar();
void MaybeRecordElementsDisplayed() const;
// Takes a popup menu (caption, overflow) and position on the screen. This is
@@ -288,7 +298,6 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void UpdateActingAsAudioControls();
// Returns true/false based on which set of controls to display.
- bool ShouldShowAudioControls() const;
bool ShouldShowVideoControls() const;
// Node
@@ -298,8 +307,14 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
bool ContainsRelatedTarget(Event*);
void HandlePointerEvent(Event*);
+ void HandleClickEvent(Event*);
void HandleTouchEvent(Event*);
+ void EnsureAnimatedArrowContainer();
+ void MaybeJump(int);
+ bool IsOnLeftSide(Event*);
+ void TapTimerFired(TimerBase*);
+
// Internal cast related methods.
void RemotePlaybackStateChanged();
void RefreshCastButtonVisibility();
@@ -347,6 +362,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
Member<MediaControlButtonPanelElement> media_button_panel_;
Member<MediaControlLoadingPanelElement> loading_panel_;
Member<MediaControlPictureInPictureButtonElement> picture_in_picture_button_;
+ Member<MediaControlAnimatedArrowContainerElement>
+ animated_arrow_container_element_;
Member<MediaControlCastButtonElement> cast_button_;
Member<MediaControlFullscreenButtonElement> fullscreen_button_;
@@ -389,9 +406,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
// touch events, we want to ignore pointerover/pointerout/pointermove events.
bool is_touch_interaction_ = false;
- // Holds the currently set --overlay-play-button-width value. Used to check if
- // we need to update.
- base::Optional<double> overlay_play_button_width_;
+ // Timer for distinguishing double-taps.
+ TaskRunnerTimer<MediaControlsImpl> tap_timer_;
bool is_test_mode_ = false;
};
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index a772b25a7f5..f636b810f95 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -72,6 +72,9 @@ class MockWebMediaPlayerForImpl : public EmptyWebMediaPlayer {
// WebMediaPlayer overrides:
WebTimeRanges Seekable() const override { return seekable_; }
bool HasVideo() const override { return true; }
+ SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
+ return SurfaceLayerMode::kAlways;
+ }
WebTimeRanges seekable_;
};
@@ -1095,34 +1098,13 @@ TEST_F(MediaControlsImplTestWithMockScheduler, AccessibleFocusShowsControls) {
EXPECT_TRUE(IsElementVisible(*panel));
platform()->RunForPeriodSeconds(2);
- EXPECT_FALSE(IsElementVisible(*panel));
-
- MediaControls().OnAccessibleFocus();
- platform()->RunForPeriodSeconds(2);
- EXPECT_TRUE(IsElementVisible(*panel));
-}
-
-TEST_F(MediaControlsImplTestWithMockScheduler,
- AccessibleFocusKeepsControlsHiddenButDisplayed) {
- EnsureSizing();
-
- Element* panel = MediaControls().PanelElement();
-
- MediaControls().MediaElement().SetSrc("http://example.com");
- MediaControls().MediaElement().Play();
-
- platform()->RunForPeriodSeconds(2);
+ SimulateHideMediaControlsTimerFired();
EXPECT_TRUE(IsElementVisible(*panel));
- MediaControls().OnAccessibleFocus();
+ MediaControls().OnAccessibleBlur();
platform()->RunForPeriodSeconds(4);
+ SimulateHideMediaControlsTimerFired();
EXPECT_FALSE(IsElementVisible(*panel));
-
- // Display is none but can't be checked via InlineStyle. Adding checks of this
- // to make sure that any one changing this assumption will have to update this
- // test.
- EXPECT_FALSE(panel->InlineStyle());
- EXPECT_NE(EDisplay::kNone, panel->EnsureComputedStyle()->Display());
}
TEST_F(MediaControlsImplTest,
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
index f11ee556b5a..0f49a4bc3a0 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc
@@ -377,7 +377,7 @@ MediaControlsOrientationLockDelegate::ComputeDeviceOrientation(
// device_orientation_angle snapped to nearest multiple of 90.
int device_orientation_angle90 =
- std::lround(device_orientation_angle / 90) * 90;
+ static_cast<int>(std::lround(device_orientation_angle / 90) * 90);
// To be considered portrait or landscape, allow the device to be rotated 23
// degrees (chosen to approximately match Android's behavior) to either side
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
index b591afcf2e2..4b2a3176e41 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
@@ -202,7 +202,7 @@ class MediaControlsOrientationLockDelegateTest
void SimulateEnterFullscreen() {
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(Video());
test::RunPendingTasks();
}
@@ -405,7 +405,7 @@ class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest
void PlayVideo() {
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Video().Play();
}
test::RunPendingTasks();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.cc
index 7eef1d4d899..3b05144a1e5 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.cc
@@ -81,9 +81,9 @@ String MediaControlsResourceLoader::GetScrubbingMessageStyleSheet() {
};
// static
-String MediaControlsResourceLoader::GetOverlayPlayStyleSheet() {
+String MediaControlsResourceLoader::GetAnimatedArrowStyleSheet() {
return ResourceBundleHelper::UncompressResourceAsString(
- IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_OVERLAY_PLAY_CSS);
+ IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_ANIMATED_ARROW_CSS);
};
// static
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h
index 2f5c2491444..40d99ace82f 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h
@@ -37,8 +37,8 @@ class MediaControlsResourceLoader
// Returns the scrubbing message stylesheet content as a string.
static String GetScrubbingMessageStyleSheet();
- // Returns the overlay play button stylesheet content as a string.
- static String GetOverlayPlayStyleSheet();
+ // Returns the animated arrow stylesheet content as a string.
+ static String GetAnimatedArrowStyleSheet();
// Returns the specific stylesheet used for media related interstitials.
static String GetMediaInterstitialsStyleSheet();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
index 66992a77f56..ad5161cf1b7 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
@@ -184,6 +185,10 @@ void MediaControlsRotateToFullscreenDelegate::OnScreenOrientationChange() {
if (!video_element_->ShouldShowControls())
return;
+ // Do not enable if controlsList=nofullscreen is used.
+ if (video_element_->ControlsListInternal()->ShouldHideFullscreen())
+ return;
+
// Only enable if the Device Orientation API can provide beta and gamma values
// that will be needed for MediaControlsOrientationLockDelegate to
// automatically unlock, such that it will be possible to exit fullscreen by
@@ -228,7 +233,8 @@ void MediaControlsRotateToFullscreenDelegate::OnScreenOrientationChange() {
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(video_element_->GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(
+ video_element_->GetDocument().GetFrame());
bool should_be_fullscreen =
current_screen_orientation_ == video_orientation;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
index ee2a82dbb4c..e36f5176532 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
@@ -220,7 +220,7 @@ void MediaControlsRotateToFullscreenDelegateTest::InitScreenAndVideo(
void MediaControlsRotateToFullscreenDelegateTest::PlayVideo() {
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
GetVideo().Play();
}
test::RunPendingTasks();
@@ -307,7 +307,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// Should start observing visibility when played.
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
GetVideo().Play();
}
test::RunPendingTasks();
@@ -328,7 +328,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// Should resume observing visibility when playback resumes.
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
GetVideo().Play();
}
test::RunPendingTasks();
@@ -622,7 +622,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// video (in this case document.body).
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(*GetDocument().body());
}
test::RunPendingTasks();
@@ -653,7 +653,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// Start in fullscreen.
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
GetMediaControls().EnterFullscreen();
}
// n.b. omit to call Fullscreen::From(GetDocument()).DidEnterFullscreen() so
@@ -684,7 +684,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// Start in fullscreen.
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
GetMediaControls().EnterFullscreen();
}
// n.b. omit to call Fullscreen::From(GetDocument()).DidEnterFullscreen() so
@@ -716,7 +716,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
// video (in this case document.body).
{
std::unique_ptr<UserGestureIndicator> gesture =
- Frame::NotifyUserActivation(GetDocument().GetFrame());
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(*GetDocument().body());
}
test::RunPendingTasks();
@@ -735,4 +735,50 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EXPECT_FALSE(GetVideo().IsFullscreen());
}
+TEST_F(MediaControlsRotateToFullscreenDelegateTest,
+ EnterFailControlsListNoFullscreen) {
+ // Portrait screen, landscape video.
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
+ EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
+
+ EXPECT_FALSE(ObservedVisibility());
+
+ GetVideo().setAttribute("controlslist", "nofullscreen");
+
+ PlayVideo();
+ UpdateVisibilityObserver();
+
+ EXPECT_TRUE(ObservedVisibility());
+
+ // Rotate screen to landscape.
+ RotateTo(kWebScreenOrientationLandscapePrimary);
+
+ // Should not enter fullscreen when controlsList=nofullscreen.
+ EXPECT_FALSE(GetVideo().IsFullscreen());
+}
+
+TEST_F(MediaControlsRotateToFullscreenDelegateTest,
+ EnterSuccessControlsListNoDownload) {
+ // Portrait screen, landscape video.
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
+ EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
+
+ EXPECT_FALSE(ObservedVisibility());
+
+ GetVideo().setAttribute("controlslist", "nodownload");
+
+ PlayVideo();
+ UpdateVisibilityObserver();
+
+ EXPECT_TRUE(ObservedVisibility());
+
+ // Rotate screen to landscape.
+ RotateTo(kWebScreenOrientationLandscapePrimary);
+
+ // Should enter fullscreen when controlsList is not set to nofullscreen.
+ EXPECT_TRUE(GetVideo().IsFullscreen());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/media_controls_resources.grd b/chromium/third_party/blink/renderer/modules/media_controls/resources/media_controls_resources.grd
index 6da1783bcc0..ff832b58baf 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/media_controls_resources.grd
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/media_controls_resources.grd
@@ -17,7 +17,7 @@
<includes>
<include name="IDR_UASTYLE_LEGACY_MEDIA_CONTROLS_ANDROID_CSS" file="legacyMediaControlsAndroid.css" type="BINDATA" compress="gzip" />
<include name="IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_TIMELINE_CSS" file="modernMediaControls_timeline.css" type="BINDATA" compress="gzip" />
- <include name="IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_OVERLAY_PLAY_CSS" file="modernMediaControls_overlay_play.css" type="BINDATA" compress="gzip" />
+ <include name="IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_ANIMATED_ARROW_CSS" file="modernMediaControls_animated_arrow.css" type="BINDATA" compress="gzip" />
<include name="IDR_SHADOWSTYLE_MODERN_MEDIA_CONTROLS_SCRUBBING_MESSAGE_CSS" file="modernMediaControls_scrubbing_message.css" type="BINDATA" compress="gzip" />
<include name="IDR_MODERN_MEDIA_CONTROLS_JUMP_SVG" file="jump_image.svg" type="BINDATA" compress="gzip" />
<include name="IDR_MODERN_MEDIA_CONTROLS_ARROW_RIGHT_SVG" file="ic_arrow_right.svg" type="BINDATA" compress="gzip" />
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
index ba69e49f0e7..9d6ecde1cef 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -250,30 +250,14 @@ video::-webkit-media-controls.sizing-small div[pseudo="-internal-media-controls-
video::-webkit-media-controls.sizing-medium div[pseudo="-internal-media-controls-button-panel" i] {
height: 64px;
line-height: 64px;
- padding: 0 32px 0 32px;
+ padding: 0 16px 0 32px;
}
/* TODO(https://crbug.com/857120): remove these rules and the sizing-large CSS class. */
video::-webkit-media-controls.sizing-large div[pseudo="-internal-media-controls-button-panel" i] {
height: 64px;
line-height: 64px;
- padding: 0 32px 0 32px;
-}
-
-/* TODO(https://crbug.com/857120): All these are the same, so these are unnecessary. */
-video::-webkit-media-controls.sizing-small [pseudo="-webkit-media-controls-current-time-display"],
-video::-webkit-media-controls.sizing-small [pseudo="-webkit-media-controls-time-remaining-display"] {
- font-size: 16px;
-}
-
-video::-webkit-media-controls.sizing-medium [pseudo="-webkit-media-controls-current-time-display"],
-video::-webkit-media-controls.sizing-medium [pseudo="-webkit-media-controls-time-remaining-display"] {
- font-size: 16px;
-}
-
-video::-webkit-media-controls.sizing-large [pseudo="-webkit-media-controls-current-time-display"],
-video::-webkit-media-controls.sizing-large [pseudo="-webkit-media-controls-time-remaining-display"] {
- font-size: 16px;
+ padding: 0 16px 0 32px;
}
audio::-webkit-media-controls-play-button,
@@ -325,8 +309,10 @@ video::-webkit-media-controls:not(.audio-only) [pseudo="-webkit-media-controls-p
}
audio::-webkit-media-controls-mute-button:disabled,
+audio::-webkit-media-controls-play-button:disabled,
video::-internal-media-controls-overflow-button:disabled,
video::-webkit-media-controls-mute-button:disabled,
+video::-webkit-media-controls-play-button:disabled,
video::-webkit-media-controls-fullscreen-button:disabled {
background-color: initial;
opacity: 0.3;
@@ -380,19 +366,19 @@ video::-webkit-media-controls:not(.audio-only) [pseudo="-webkit-media-controls-p
video::-webkit-media-controls-overlay-play-button {
-webkit-appearance: -internal-media-control;
- display: flex;
- justify-content: center;
- align-items: center;
- flex: 1;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ margin-left: -56px /* (72px play button width / -2) - 20px padding */;
+ margin-top: -68px /* ((72px play button width + 24px timeline height + padding-bottom) / -2) - 20px padding */;
min-height: 0;
- width: 100%;
- box-sizing: border-box;
+ width: fit-content;
overflow: hidden;
background: transparent;
- margin-bottom: -48px;
- position: relative;
opacity: 1;
transition: opacity 0.25s cubic-bezier(0.25, 0.1, 0.25, 1);
+ padding: 20px;
+ border: 0;
}
/**
@@ -410,8 +396,8 @@ video::-webkit-media-controls-overlay-play-button.hidden {
}
input[pseudo="-webkit-media-controls-overlay-play-button" i]::-internal-media-controls-overlay-play-button-internal {
- width: var(--overlay-play-button-width, 48px);
- height: var(--overlay-play-button-width, 48px);
+ width: 72px;
+ height: 72px;
border-radius: 50%;
background-size: 50%;
@@ -437,17 +423,11 @@ video::-webkit-media-controls.state-playing:not(.audio-only) input[pseudo="-webk
background-image: -webkit-image-set(url(ic_pause_white.svg) 1x);
}
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-overlay-play-button" i] {
- margin-bottom: -48px;
-}
-
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-overlay-play-button" i] {
- margin-bottom: -64px;
-}
-
-/* TODO(https://crbug.com/857120): remove these rules and the sizing-large CSS class. */
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-overlay-play-button" i] {
- margin-bottom: -64px;
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-play-button"] {
+ /* Undo the extra 16px of left padding on the button panel. We only want that
+ * extra padding when the current time is the leftmost item, and not when the
+ * play button is leftmost. */
+ margin-left: -16px;
}
/**
@@ -478,95 +458,53 @@ video::-webkit-media-controls-timeline {
}
video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i] {
- padding: 0 16px 12px 16px;
+ padding: 0 16px 20px 16px;
}
video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i] {
- padding: 0 32px 36px 32px;
+ padding: 0 32px 20px 32px;
}
/* TODO(https://crbug.com/857120): remove these rules and the sizing-large CSS class. */
video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i] {
- padding: 0 32px 36px 32px;
-}
-
-/* TODO(https://crbug.com/857120): All these are the same, so these are unnecessary. */
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i],
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background {
- height: 4px;
-}
-
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i],
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background {
- height: 4px;
+ padding: 0 32px 20px 32px;
}
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i],
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background {
+input[pseudo="-webkit-media-controls-timeline" i],
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background,
+input[pseudo="-webkit-media-controls-volume-slider" i],
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-before,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-background {
height: 4px;
}
-/* TODO(https://crbug.com/857120): All these are the same, so these are unnecessary. */
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
- width: 12px;
- height: 12px;
- margin-top: -4px;
-}
-
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
+input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-webkit-slider-thumb {
width: 12px;
height: 12px;
margin-top: -4px;
}
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
- width: 12px;
- height: 12px;
- margin-top: -4px;
-}
-
-/* TODO(https://crbug.com/857120): All these are the same, so these are unnecessary. */
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
- border-radius: 2px;
-}
-
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
- border-radius: 2px;
-}
-
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
-video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-media-controls-segmented-track {
border-radius: 2px;
}
-video::-webkit-media-controls.sizing-small div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-frame {
- margin-top: calc(
- (var(--overlay-play-button-width, 48px)
- + 16px /* timeline height + padding-bottom */)
- / -2);
-}
-
-video::-webkit-media-controls.sizing-medium div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-frame {
- margin-top: calc(
- (var(--overlay-play-button-width, 48px)
- + 40px /* timeline height + padding-bottom */)
- / -2);
-}
+video::-webkit-media-controls div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-frame {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ overflow: hidden;
-/* TODO(https://crbug.com/857120): remove these rules and the sizing-large CSS class. */
-video::-webkit-media-controls.sizing-large div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-frame {
- margin-top: calc(
- (var(--overlay-play-button-width, 48px)
- + 40px /* timeline height + padding-bottom */)
- / -2);
+ height: 72px /* overlay play button height */;
+ width: 72px /* overlay play button width */;
+ margin-left: -36px /* (72px overlay play button width / -2) */;
+ margin-top: -48px /* (72px overlay play button height + 24px timeline height + padding-bottom) / -2) */;
}
div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-mask-1-background {
@@ -583,7 +521,8 @@ div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls
background-position: center right;
}
-input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-media-controls-segmented-track {
-webkit-appearance: -internal-media-control;
flex: 1;
@@ -591,12 +530,14 @@ input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segm
border-radius: 2px;
position: relative;
}
-video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track,
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-media-controls-segmented-track {
background: rgba(255, 255, 255, .3);
box-shadow: 0 2px 10px 0 rgba(0,0,0,0.5);
}
-input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
+input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-webkit-slider-thumb {
-webkit-appearance: -internal-media-control;
background: rgba(0, 0, 0, .87);
box-shadow: 0 0 10px 0 #fff;
@@ -608,7 +549,8 @@ input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
flex: 0 0 0;
}
-video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb {
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-webkit-slider-thumb,
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-volume-slider" i]::-webkit-slider-thumb {
background: #FFFFFF;
box-shadow: unset;
}
@@ -617,7 +559,8 @@ video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-contr
display: none;
}
-input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-background,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-background {
position: absolute;
width: 100%;
top: 0;
@@ -626,30 +569,58 @@ input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-backg
}
input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
-input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-before,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-after {
position: absolute;
height: 4px;
}
-input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-before {
background: rgba(0, 0, 0, .87);
border-radius: 100px;
}
-video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before {
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-before,
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-before {
background: rgba(255, 255, 255, 1);
}
-input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after {
+input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
+input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-after {
background: rgba(0, 0, 0, .54);
border-radius: 2px;
}
-video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after {
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-timeline" i]::-internal-track-segment-highlight-after,
+video::-webkit-media-controls:not(.audio-only) input[pseudo="-webkit-media-controls-volume-slider" i]::-internal-track-segment-highlight-after {
background: rgba(255, 255, 255, .54);
}
audio::-webkit-media-controls-volume-slider,
video::-webkit-media-controls-volume-slider {
- display: none;
+ -webkit-appearance: -internal-media-control;
+
+ height: 4px;
+ width: 52px;
+ transition: width 0.3s;
+ margin: 0;
+ padding: 22px 0; /* (48px button panel height - 4px slider height) / 2 */
+ background: transparent;
+ /* This prevents layout issues in quirks mode. */
+ box-sizing: unset !important;
+}
+
+audio::-webkit-media-controls-volume-slider.closed,
+video::-webkit-media-controls-volume-slider.closed {
+ width: 0;
+ opacity: 0;
+ pointer-events: none;
+ transition: width 0.3s ease, opacity 0.28s step-end;
+}
+
+video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-volume-slider" i],
+video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-volume-slider" i] {
+ padding: 30px 0; /* (64px button panel height - 4px slider height) / 2 */
}
/**
@@ -852,12 +823,6 @@ audio {
height: 54px;
}
-audio::-webkit-media-controls,
-video::-webkit-media-controls.audio-only {
- min-width: 240px;
- min-height: 54px;
-}
-
audio::-webkit-media-controls-overlay-enclosure,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-overlay-enclosure"] {
display: none;
@@ -865,7 +830,6 @@ video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-overlay
audio::-webkit-media-controls-enclosure,
video::-webkit-media-controls.audio-only [pseudo="-webkit-media-controls-enclosure"] {
- min-height: 54px;
max-height: 54px;
flex-direction: row;
background: #F1F3F4;
@@ -951,6 +915,28 @@ video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-loadi
}
/**
+ * Animated Arrow Container
+ */
+
+video::-internal-media-controls-animated-arrow-container {
+ position: absolute;
+ display: flex;
+ align-items: center;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ overflow: hidden;
+ z-index: 1;
+ pointer-events: none;
+}
+
+audio::-internal-media-controls-animated-arrow-container,
+video::-webkit-media-controls.audio-only [pseudo="-internal-media-controls-animated-arrow-container"] {
+ display: none;
+}
+
+/**
* Text Tracks
*/
video::-webkit-media-text-track-container {
@@ -1120,6 +1106,11 @@ video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-control
margin-top: -5px;
}
+video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-controls-overlay-play-button" i] {
+ margin-left: -52px /* (play button width / 2) + 20px Padding */;
+ margin-top: -64px /* (play button width + timeline height + padding-bottom) / 2 + padding */
+}
+
video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-controls-overlay-play-button" i]::-internal-media-controls-overlay-play-button-internal {
width: 64px;
height: 64px;
@@ -1127,6 +1118,14 @@ video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-control
background-size: 36px;
}
+video::-webkit-media-controls.immersive-mode div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-frame {
+ width: 64px; /* play button width */
+ height: 64px; /* play button width */
+ margin-top: -44px; /* (play button width + timeline height + padding-bottom) / -2 */
+ margin-left: -32px; /* play button width / -2 */
+}
+
+
video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-controls-mute-button" i],
video::-webkit-media-controls.immersive-mode input[pseudo="-webkit-media-controls-fullscreen-button" i],
video::-webkit-media-controls.immersive-mode input[pseudo="-internal-media-controls-overflow-button" i] {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_overlay_play.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_animated_arrow.css
index b5dfd5231f6..ef090b912e9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_overlay_play.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_animated_arrow.css
@@ -5,6 +5,7 @@
#left-arrow,
#right-arrow {
flex: 1;
+ text-align: center;
}
#left-arrow svg,
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
index 932651f1f63..d70707c79f8 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
@@ -2,16 +2,6 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.*/
-#spinner-frame {
- position: absolute;
- height: var(--overlay-play-button-width, 48px);
- width: var(--overlay-play-button-width, 48px);
- top: 50%;
- left: 50%;
- margin-left: calc(var(--overlay-play-button-width) / -2);
- overflow: hidden;
-}
-
#spinner {
animation: container-rotate 1568ms linear infinite;
height: 100%;
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
index fa721b21655..c396e06ea9b 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
@@ -84,11 +84,11 @@ void MediaElementEventListener::handleEvent(ExecutionContext* context,
: MediaStreamRegistry::Registry().LookupMediaStreamDescriptor(
media_element_->currentSrc().GetString());
DCHECK(descriptor);
- for (size_t i = 0; i < descriptor->NumberOfAudioComponents(); i++) {
+ for (unsigned i = 0; i < descriptor->NumberOfAudioComponents(); i++) {
media_stream_->AddTrackByComponentAndFireEvents(
descriptor->AudioComponent(i));
}
- for (size_t i = 0; i < descriptor->NumberOfVideoComponents(); i++) {
+ for (unsigned i = 0; i < descriptor->NumberOfVideoComponents(); i++) {
media_stream_->AddTrackByComponentAndFireEvents(
descriptor->VideoComponent(i));
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
index 7aaa74951db..6b80cf3a665 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -174,8 +174,13 @@ MediaRecorder::MediaRecorder(ExecutionContext* context,
this,
&MediaRecorder::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kDOMManipulation))) {
- DCHECK(stream_->getTracks().size());
+ if (context->IsContextDestroyed()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "Execution context is detached.");
+ return;
+ }
+ DCHECK(stream_->getTracks().size());
recorder_handler_ = Platform::Current()->CreateMediaRecorderHandler(
context->GetTaskRunner(TaskType::kInternalMediaRealTime));
DCHECK(recorder_handler_);
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
index 831942c83cb..caaa6a4dc92 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
@@ -55,7 +55,7 @@ Vector<v8::Local<v8::Value>> MediaMetadata::artwork(
ScriptState* script_state) const {
Vector<v8::Local<v8::Value>> result(artwork_.size());
- for (size_t i = 0; i < artwork_.size(); ++i) {
+ for (wtf_size_t i = 0; i < artwork_.size(); ++i) {
result[i] = FreezeV8Object(ToV8(artwork_[i], script_state),
script_state->GetIsolate());
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
index 1ba96056294..697e0f48ffc 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
@@ -194,9 +194,7 @@ mojom::blink::MediaSessionService* MediaSession::GetService() {
if (!GetExecutionContext())
return nullptr;
- DCHECK(GetExecutionContext()->IsDocument())
- << "MediaSession::getService() is only available from a frame";
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
LocalFrame* frame = document->GetFrame();
if (!frame)
return nullptr;
@@ -216,10 +214,10 @@ mojom::blink::MediaSessionService* MediaSession::GetService() {
void MediaSession::DidReceiveAction(
blink::mojom::blink::MediaSessionAction action) {
- DCHECK(GetExecutionContext()->IsDocument());
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(document ? document->GetFrame() : nullptr);
+ LocalFrame::NotifyUserActivation(document ? document->GetFrame()
+ : nullptr);
auto iter = action_handlers_.find(MojomActionToActionName(action));
if (iter == action_handlers_.end())
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
index 1fba87ab4b0..2591f3459fe 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -269,7 +269,7 @@ void MediaSource::OnReadyStateChange(const AtomicString& old_state,
active_source_buffers_->Clear();
// Clear SourceBuffer references to this object.
- for (unsigned long i = 0; i < source_buffers_->length(); ++i)
+ for (unsigned i = 0; i < source_buffers_->length(); ++i)
source_buffers_->item(i)->RemovedFromMediaSource();
source_buffers_->Clear();
@@ -280,7 +280,7 @@ void MediaSource::OnReadyStateChange(const AtomicString& old_state,
bool MediaSource::IsUpdating() const {
// Return true if any member of |m_sourceBuffers| is updating.
- for (unsigned long i = 0; i < source_buffers_->length(); ++i) {
+ for (unsigned i = 0; i < source_buffers_->length(); ++i) {
if (source_buffers_->item(i)->updating())
return true;
}
@@ -379,7 +379,7 @@ TimeRanges* MediaSource::Buffered() const {
// Implements MediaSource algorithm for HTMLMediaElement.buffered.
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
HeapVector<Member<TimeRanges>> ranges(active_source_buffers_->length());
- for (size_t i = 0; i < active_source_buffers_->length(); ++i)
+ for (unsigned i = 0; i < active_source_buffers_->length(); ++i)
ranges[i] = active_source_buffers_->item(i)->buffered(ASSERT_NO_EXCEPTION);
// 1. If activeSourceBuffers.length equals 0 then return an empty TimeRanges
@@ -391,7 +391,7 @@ TimeRanges* MediaSource::Buffered() const {
// SourceBuffer object in activeSourceBuffers.
// 3. Let highest end time be the largest range end time in the active ranges.
double highest_end_time = -1;
- for (size_t i = 0; i < ranges.size(); ++i) {
+ for (wtf_size_t i = 0; i < ranges.size(); ++i) {
unsigned length = ranges[i]->length();
if (length)
highest_end_time = std::max(
@@ -409,7 +409,7 @@ TimeRanges* MediaSource::Buffered() const {
// 5. For each SourceBuffer object in activeSourceBuffers run the following
// steps:
bool ended = readyState() == EndedKeyword();
- for (size_t i = 0; i < ranges.size(); ++i) {
+ for (wtf_size_t i = 0; i < ranges.size(); ++i) {
// 5.1 Let source ranges equal the ranges returned by the buffered attribute
// on the current SourceBuffer.
TimeRanges* source_ranges = ranges[i].Get();
@@ -545,7 +545,7 @@ void MediaSource::DurationChangeAlgorithm(double new_duration,
// media are disallowed. When truncation is necessary, use remove() to
// reduce the buffered range before updating duration.
double highest_buffered_presentation_timestamp = 0;
- for (size_t i = 0; i < source_buffers_->length(); ++i) {
+ for (unsigned i = 0; i < source_buffers_->length(); ++i) {
highest_buffered_presentation_timestamp =
std::max(highest_buffered_presentation_timestamp,
source_buffers_->item(i)->HighestPresentationTimestamp());
@@ -582,7 +582,7 @@ void MediaSource::DurationChangeAlgorithm(double new_duration,
// Deprecated behavior: if the new duration is less than old duration,
// then call remove(new duration, old duration) on all all objects in
// sourceBuffers.
- for (size_t i = 0; i < source_buffers_->length(); ++i)
+ for (unsigned i = 0; i < source_buffers_->length(); ++i)
source_buffers_->item(i)->remove(new_duration, old_duration,
ASSERT_NO_EXCEPTION);
}
@@ -716,10 +716,10 @@ void MediaSource::SetSourceBufferActive(SourceBuffer* source_buffer,
// SourceBuffer transitions to active are not guaranteed to occur in the
// same order as buffers in |m_sourceBuffers|, so this method needs to
// insert |sourceBuffer| into |m_activeSourceBuffers|.
- size_t index_in_source_buffers = source_buffers_->Find(source_buffer);
+ wtf_size_t index_in_source_buffers = source_buffers_->Find(source_buffer);
DCHECK(index_in_source_buffers != kNotFound);
- size_t insert_position = 0;
+ wtf_size_t insert_position = 0;
while (insert_position < active_source_buffers_->length() &&
source_buffers_->Find(active_source_buffers_->item(insert_position)) <
index_in_source_buffers) {
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
index 950e216464c..84c35851400 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
@@ -49,27 +49,28 @@ void MediaSourceRegistry::RegisterURL(SecurityOrigin*,
MediaSource* source = static_cast<MediaSource*>(registrable);
source->AddedToRegistry();
- media_sources_.Set(url.GetString(), source);
+ media_sources_->Set(url.GetString(), source);
}
void MediaSourceRegistry::UnregisterURL(const KURL& url) {
DCHECK(IsMainThread());
- PersistentHeapHashMap<String, Member<MediaSource>>::iterator iter =
- media_sources_.find(url.GetString());
- if (iter == media_sources_.end())
+ HeapHashMap<String, Member<MediaSource>>::iterator iter =
+ media_sources_->find(url.GetString());
+ if (iter == media_sources_->end())
return;
MediaSource* source = iter->value;
- media_sources_.erase(iter);
+ media_sources_->erase(iter);
source->RemovedFromRegistry();
}
URLRegistrable* MediaSourceRegistry::Lookup(const String& url) {
DCHECK(IsMainThread());
- return url.IsNull() ? nullptr : media_sources_.at(url);
+ return url.IsNull() ? nullptr : media_sources_->at(url);
}
-MediaSourceRegistry::MediaSourceRegistry() {
+MediaSourceRegistry::MediaSourceRegistry()
+ : media_sources_(new HeapHashMap<String, Member<MediaSource>>) {
HTMLMediaSource::SetRegistry(this);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
index b9a7fed0f2d..84b1ec57e34 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
@@ -34,6 +34,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -54,7 +55,7 @@ class MediaSourceRegistry final : public URLRegistry {
private:
MediaSourceRegistry();
- PersistentHeapHashMap<String, Member<MediaSource>> media_sources_;
+ Persistent<HeapHashMap<String, Member<MediaSource>>> media_sources_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
index 8007d2c1f32..a495b2e2be6 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -939,7 +939,7 @@ bool SourceBuffer::InitializationSegmentReceived(
// tracks), then the Track IDs match the ones in the first initialization
// segment.
if (tracks_match_first_init_segment && new_audio_tracks.size() > 1) {
- for (size_t i = 0; i < new_audio_tracks.size(); ++i) {
+ for (wtf_size_t i = 0; i < new_audio_tracks.size(); ++i) {
const String& new_track_id = new_video_tracks[i].id;
if (new_track_id !=
String(audioTracks().AnonymousIndexedGetter(i)->id())) {
@@ -950,7 +950,7 @@ bool SourceBuffer::InitializationSegmentReceived(
}
if (tracks_match_first_init_segment && new_video_tracks.size() > 1) {
- for (size_t i = 0; i < new_video_tracks.size(); ++i) {
+ for (wtf_size_t i = 0; i < new_video_tracks.size(); ++i) {
const String& new_track_id = new_video_tracks[i].id;
if (new_track_id !=
String(videoTracks().AnonymousIndexedGetter(i)->id())) {
@@ -1312,7 +1312,7 @@ void SourceBuffer::AppendBufferAsyncPart() {
// 1. Run the segment parser loop algorithm.
// Step 2 doesn't apply since we run Step 1 synchronously here.
DCHECK_GE(pending_append_data_.size(), pending_append_data_offset_);
- size_t append_size =
+ wtf_size_t append_size =
pending_append_data_.size() - pending_append_data_offset_;
// Impose an arbitrary max size for a single append() call so that an append
@@ -1320,13 +1320,12 @@ void SourceBuffer::AppendBufferAsyncPart() {
// by looking at YouTube SourceBuffer usage across a variety of bitrates.
// This value allows relatively large appends while keeping append() call
// duration in the ~5-15ms range.
- const size_t kMaxAppendSize = 128 * 1024;
+ const wtf_size_t kMaxAppendSize = 128 * 1024;
if (append_size > kMaxAppendSize)
append_size = kMaxAppendSize;
TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this,
- "appending", "appendSize",
- static_cast<unsigned>(append_size));
+ "appending", "appendSize", append_size);
// |zero| is used for 0 byte appends so we always have a valid pointer.
// We need to convey all appends, even 0 byte ones to |m_webSourceBuffer|
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
index 0503186677f..e77eb497dd3 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -38,8 +38,6 @@ blink_modules_sources("mediastream") {
"navigator_user_media.h",
"overconstrained_error.cc",
"overconstrained_error.h",
- "url_media_stream.cc",
- "url_media_stream.h",
"user_media_client.cc",
"user_media_client.h",
"user_media_controller.cc",
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
index 068058a8acb..e34bb663e14 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
@@ -64,12 +64,7 @@ struct NameValueStringConstraint {
};
// Legal constraint names.
-// Temporary Note: Comments about source are where they are copied from.
-// Once the chrome parts use the new-style constraint values, they will
-// be deleted from the files mentioned.
-// TODO(hta): remove comments before https://crbug.com/543997 is closed.
-// From content/renderer/media/stream/media_stream_video_source.cc
const char kMinAspectRatio[] = "minAspectRatio";
const char kMaxAspectRatio[] = "maxAspectRatio";
const char kMaxWidth[] = "maxWidth";
@@ -78,17 +73,15 @@ const char kMaxHeight[] = "maxHeight";
const char kMinHeight[] = "minHeight";
const char kMaxFrameRate[] = "maxFrameRate";
const char kMinFrameRate[] = "minFrameRate";
-// From content/common/media/media_stream_options.cc
const char kMediaStreamSource[] = "chromeMediaSource";
const char kMediaStreamSourceId[] =
"chromeMediaSourceId"; // mapped to deviceId
const char kMediaStreamSourceInfoId[] = "sourceId"; // mapped to deviceId
const char kMediaStreamRenderToAssociatedSink[] =
"chromeRenderToAssociatedSink";
-// RenderToAssociatedSink will be going away in M50-M60 some time.
+// RenderToAssociatedSink will be going away some time.
const char kMediaStreamAudioHotword[] = "googHotword";
// TODO(hta): googHotword should go away. https://crbug.com/577627
-// From content/renderer/media/stream/media_stream_audio_processor_options.cc
const char kEchoCancellation[] = "echoCancellation";
const char kDisableLocalEcho[] = "disableLocalEcho";
const char kGoogEchoCancellation[] = "googEchoCancellation";
@@ -102,13 +95,8 @@ const char kGoogArrayGeometry[] = "googArrayGeometry";
const char kGoogHighpassFilter[] = "googHighpassFilter";
const char kGoogTypingNoiseDetection[] = "googTypingNoiseDetection";
const char kGoogAudioMirroring[] = "googAudioMirroring";
-
-// From
-// third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.cc
-
// Audio constraints.
const char kDAEchoCancellation[] = "googDAEchoCancellation";
-
// Google-specific constraint keys for a local video source (getUserMedia).
const char kNoiseReduction[] = "googNoiseReduction";
@@ -139,11 +127,8 @@ const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold";
const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage";
const char kHighStartBitrate[] = "googHighStartBitrate";
const char kPayloadPadding[] = "googPayloadPadding";
-// From webrtc_audio_capturer
const char kAudioLatency[] = "latencyMs";
-// From media_stream_video_capturer_source
-// End of names from libjingle
// Names that have been used in the past, but should now be ignored.
// Kept around for backwards compatibility.
// https://crbug.com/579729
@@ -428,12 +413,10 @@ static void ParseOldStyleNames(
result.goog_payload_padding.SetExact(ToBoolean(constraint.value_));
} else if (constraint.name_.Equals(kAudioLatency)) {
result.goog_latency_ms.SetExact(atoi(constraint.value_.Utf8().c_str()));
- } else if (constraint.name_.Equals(kPowerLineFrequency)) {
- result.goog_power_line_frequency.SetExact(
- atoi(constraint.value_.Utf8().c_str()));
} else if (constraint.name_.Equals(kGoogLeakyBucket) ||
constraint.name_.Equals(kGoogBeamforming) ||
- constraint.name_.Equals(kGoogArrayGeometry)) {
+ constraint.name_.Equals(kGoogArrayGeometry) ||
+ constraint.name_.Equals(kPowerLineFrequency)) {
// TODO(crbug.com/856176): Remove the kGoogBeamforming and
// kGoogArrayGeometry special cases.
context->AddConsoleMessage(ConsoleMessage::Create(
@@ -793,7 +776,7 @@ bool UseNakedNumeric(T input, NakedValueDisposition which) {
}
NOTREACHED();
return false;
-};
+}
template <class T>
bool UseNakedNonNumeric(T input, NakedValueDisposition which) {
@@ -807,7 +790,7 @@ bool UseNakedNonNumeric(T input, NakedValueDisposition which) {
}
NOTREACHED();
return false;
-};
+}
template <typename U, class T>
U GetNakedValue(T input, NakedValueDisposition which) {
@@ -821,7 +804,7 @@ U GetNakedValue(T input, NakedValueDisposition which) {
}
NOTREACHED();
return input.Exact();
-};
+}
LongOrConstrainLongRange ConvertLong(const LongConstraint& input,
NakedValueDisposition naked_treatment) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
index 03a93fb8a5c..19ccd3104c1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -82,7 +82,7 @@ MediaDevices::~MediaDevices() = default;
ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) {
Platform::Current()->UpdateWebRTCAPICount(WebRTCAPIName::kEnumerateDevices);
LocalFrame* frame =
- ToDocument(ExecutionContext::From(script_state))->GetFrame();
+ To<Document>(ExecutionContext::From(script_state))->GetFrame();
if (!frame) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError,
@@ -118,7 +118,7 @@ ScriptPromise MediaDevices::SendUserMediaRequest(
PromiseResolverCallbacks* callbacks =
PromiseResolverCallbacks::Create(resolver);
- Document* document = ToDocument(ExecutionContext::From(script_state));
+ Document* document = To<Document>(ExecutionContext::From(script_state));
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (!user_media)
@@ -212,7 +212,7 @@ void MediaDevices::Unpause() {
void MediaDevices::OnDevicesChanged(
MediaDeviceType type,
Vector<mojom::blink::MediaDeviceInfoPtr> device_infos) {
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
DCHECK(document);
if (RuntimeEnabledFeatures::OnDeviceChangeEnabled())
@@ -240,7 +240,7 @@ void MediaDevices::StartObserving() {
if (binding_.is_bound() || stopped_)
return;
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
if (!document || !document->GetFrame())
return;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index 8752d092203..daf9d684dd3 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -198,9 +198,9 @@ class PromiseObserver {
class MediaDevicesTest : public testing::Test {
public:
- using MediaDeviceInfos = PersistentHeapVector<Member<MediaDeviceInfo>>;
+ using MediaDeviceInfos = HeapVector<Member<MediaDeviceInfo>>;
- MediaDevicesTest() {
+ MediaDevicesTest() : device_infos_(new MediaDeviceInfos) {
dispatcher_host_ = std::make_unique<MockMediaDevicesDispatcherHost>();
}
@@ -224,7 +224,7 @@ class MediaDevicesTest : public testing::Test {
void DevicesEnumerated(const MediaDeviceInfoVector& device_infos) {
devices_enumerated_ = true;
for (size_t i = 0; i < device_infos.size(); i++) {
- device_infos_.push_back(MediaDeviceInfo::Create(
+ device_infos_->push_back(MediaDeviceInfo::Create(
device_infos[i]->deviceId(), device_infos[i]->label(),
device_infos[i]->groupId(), device_infos[i]->DeviceType()));
}
@@ -247,7 +247,7 @@ class MediaDevicesTest : public testing::Test {
bool listener_connection_error() const { return listener_connection_error_; }
- const MediaDeviceInfos& device_infos() const { return device_infos_; }
+ const MediaDeviceInfos& device_infos() const { return *device_infos_; }
bool devices_enumerated() const { return devices_enumerated_; }
@@ -264,7 +264,7 @@ class MediaDevicesTest : public testing::Test {
private:
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
std::unique_ptr<MockMediaDevicesDispatcherHost> dispatcher_host_;
- MediaDeviceInfos device_infos_;
+ Persistent<MediaDeviceInfos> device_infos_;
bool devices_enumerated_ = false;
bool dispatcher_host_connection_error_ = false;
bool device_changed_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
index d48dfc7daa1..feef966d923 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -48,9 +48,6 @@ static bool ContainsSource(MediaStreamTrackVector& track_vector,
static void ProcessTrack(MediaStreamTrack* track,
MediaStreamTrackVector& track_vector) {
- if (track->Ended())
- return;
-
MediaStreamSource* source = track->Component()->Source();
if (!ContainsSource(track_vector, source))
track_vector.push_back(track);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.cc
index 7a6715dd1d4..db5b71d3df5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.cc
@@ -43,27 +43,29 @@ void MediaStreamRegistry::RegisterURL(SecurityOrigin*,
URLRegistrable* stream) {
DCHECK(&stream->Registry() == this);
DCHECK(IsMainThread());
- stream_descriptors_.Set(url.GetString(),
- static_cast<MediaStream*>(stream)->Descriptor());
+ stream_descriptors_->Set(url.GetString(),
+ static_cast<MediaStream*>(stream)->Descriptor());
}
void MediaStreamRegistry::UnregisterURL(const KURL& url) {
DCHECK(IsMainThread());
- stream_descriptors_.erase(url.GetString());
+ stream_descriptors_->erase(url.GetString());
}
bool MediaStreamRegistry::Contains(const String& url) {
DCHECK(IsMainThread());
- return stream_descriptors_.Contains(url);
+ return stream_descriptors_->Contains(url);
}
MediaStreamDescriptor* MediaStreamRegistry::LookupMediaStreamDescriptor(
const String& url) {
DCHECK(IsMainThread());
- return stream_descriptors_.at(url);
+ return stream_descriptors_->at(url);
}
-MediaStreamRegistry::MediaStreamRegistry() {
+MediaStreamRegistry::MediaStreamRegistry()
+ : stream_descriptors_(
+ new HeapHashMap<String, Member<MediaStreamDescriptor>>) {
HTMLMediaElement::SetMediaStreamRegistry(this);
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.h
index 014d7e9fa36..8f34641d7bc 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_registry.h
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -50,7 +51,7 @@ class MODULES_EXPORT MediaStreamRegistry final : public URLRegistry {
private:
MediaStreamRegistry();
- PersistentHeapHashMap<String, Member<MediaStreamDescriptor>>
+ Persistent<HeapHashMap<String, Member<MediaStreamDescriptor>>>
stream_descriptors_;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 666ef98d3a4..062a7c5a0a7 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -71,10 +71,12 @@ bool ConstraintSetHasImageCapture(
constraint_set.hasExposureMode() || constraint_set.hasFocusMode() ||
constraint_set.hasPointsOfInterest() ||
constraint_set.hasExposureCompensation() ||
+ constraint_set.hasExposureTime() ||
constraint_set.hasColorTemperature() || constraint_set.hasIso() ||
constraint_set.hasBrightness() || constraint_set.hasContrast() ||
constraint_set.hasSaturation() || constraint_set.hasSharpness() ||
- constraint_set.hasZoom() || constraint_set.hasTorch();
+ constraint_set.hasFocusDistance() || constraint_set.hasZoom() ||
+ constraint_set.hasTorch();
}
bool ConstraintSetHasNonImageCapture(
@@ -294,7 +296,7 @@ void MediaStreamTrack::stopTrack(ExecutionContext* execution_context) {
return;
ready_state_ = MediaStreamSource::kReadyStateEnded;
- Document* document = ToDocument(execution_context);
+ Document* document = To<Document>(execution_context);
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (user_media)
@@ -320,8 +322,8 @@ void MediaStreamTrack::SetConstraints(const WebMediaConstraints& constraints) {
void MediaStreamTrack::getCapabilities(MediaTrackCapabilities& capabilities) {
if (image_capture_)
capabilities = image_capture_->GetMediaTrackCapabilities();
-
auto platform_capabilities = component_->Source()->GetCapabilities();
+
capabilities.setDeviceId(platform_capabilities.device_id);
if (!platform_capabilities.group_id.IsNull())
capabilities.setGroupId(platform_capabilities.group_id);
@@ -405,12 +407,14 @@ void MediaStreamTrack::getConstraints(MediaTrackConstraints& constraints) {
image_capture_constraints.hasExposureMode() ||
image_capture_constraints.hasFocusMode() ||
image_capture_constraints.hasExposureCompensation() ||
+ image_capture_constraints.hasExposureTime() ||
image_capture_constraints.hasColorTemperature() ||
image_capture_constraints.hasIso() ||
image_capture_constraints.hasBrightness() ||
image_capture_constraints.hasContrast() ||
image_capture_constraints.hasSaturation() ||
image_capture_constraints.hasSharpness() ||
+ image_capture_constraints.hasFocusDistance() ||
image_capture_constraints.hasZoom()) {
// Add image capture constraints, if any, as another entry to advanced().
vector.emplace_back(image_capture_constraints);
@@ -493,6 +497,42 @@ void MediaStreamTrack::getSettings(MediaTrackSettings& settings) {
if (image_capture_)
image_capture_->GetMediaTrackSettings(settings);
+
+ if (platform_settings.display_surface) {
+ WTF::String value;
+ switch (platform_settings.display_surface.value()) {
+ case WebMediaStreamTrack::DisplayCaptureSurfaceType::kMonitor:
+ value = "monitor";
+ break;
+ case WebMediaStreamTrack::DisplayCaptureSurfaceType::kWindow:
+ value = "window";
+ break;
+ case WebMediaStreamTrack::DisplayCaptureSurfaceType::kApplication:
+ value = "application";
+ break;
+ case WebMediaStreamTrack::DisplayCaptureSurfaceType::kBrowser:
+ value = "browser";
+ break;
+ }
+ settings.setDisplaySurface(value);
+ }
+ if (platform_settings.logical_surface)
+ settings.setLogicalSurface(platform_settings.logical_surface.value());
+ if (platform_settings.cursor) {
+ WTF::String value;
+ switch (platform_settings.cursor.value()) {
+ case WebMediaStreamTrack::CursorCaptureType::kNever:
+ value = "never";
+ break;
+ case WebMediaStreamTrack::CursorCaptureType::kAlways:
+ value = "always";
+ break;
+ case WebMediaStreamTrack::CursorCaptureType::kMotion:
+ value = "motion";
+ break;
+ }
+ settings.setCursor(value);
+ }
}
ScriptPromise MediaStreamTrack::applyConstraints(
@@ -543,7 +583,7 @@ ScriptPromise MediaStreamTrack::applyConstraints(
return promise;
}
- Document* document = ToDocument(execution_context);
+ Document* document = To<Document>(execution_context);
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (!user_media) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
index 3a56aa445ee..b6f68f95aec 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
@@ -23,12 +23,14 @@ dictionary MediaTrackCapabilities {
sequence<DOMString> exposureMode;
sequence<DOMString> focusMode;
MediaSettingsRange exposureCompensation;
+ MediaSettingsRange exposureTime;
MediaSettingsRange colorTemperature;
MediaSettingsRange iso;
MediaSettingsRange brightness;
MediaSettingsRange contrast;
MediaSettingsRange saturation;
MediaSettingsRange sharpness;
+ MediaSettingsRange focusDistance;
MediaSettingsRange zoom;
boolean torch;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
index d4f9b77c330..08ce2d9c22e 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
@@ -47,12 +47,14 @@ dictionary MediaTrackConstraintSet {
ConstrainDOMString focusMode;
ConstrainPoint2D pointsOfInterest;
ConstrainDouble exposureCompensation;
+ ConstrainDouble exposureTime;
ConstrainDouble colorTemperature;
ConstrainDouble iso;
ConstrainDouble brightness;
ConstrainDouble contrast;
ConstrainDouble saturation;
ConstrainDouble sharpness;
+ ConstrainDouble focusDistance;
ConstrainDouble zoom;
ConstrainBoolean torch;
// The "mandatory" and "_optional" members are retained for conformance
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_settings.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
index 20d06f4e29c..8daf0e93368 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
@@ -40,12 +40,20 @@ dictionary MediaTrackSettings {
DOMString focusMode;
sequence<Point2D> pointsOfInterest;
double exposureCompensation;
+ double exposureTime;
double colorTemperature;
double iso;
double brightness;
double contrast;
double saturation;
double sharpness;
+ double focusDistance;
double zoom;
boolean torch;
+
+ // Screen Capture API
+ // https://w3c.github.io/mediacapture-screen-share
+ [RuntimeEnabled=GetDisplayMedia] DOMString displaySurface;
+ [RuntimeEnabled=GetDisplayMedia] boolean logicalSurface;
+ [RuntimeEnabled=GetDisplayMedia] DOMString cursor;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl
index 0e67999ce01..8d288b623ef 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl
@@ -46,12 +46,14 @@ dictionary MediaTrackSupportedConstraints {
boolean focusMode = true;
boolean pointsOfInterest = true;
boolean exposureCompensation = true;
+ boolean exposureTime = true;
boolean colorTemperature = true;
boolean iso = true;
boolean brightness = true;
boolean contrast = true;
boolean saturation = true;
boolean sharpness = true;
+ boolean focusDistance = true;
boolean zoom = true;
boolean torch = true;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.cc b/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.cc
deleted file mode 100644
index 047ff7b3d3b..00000000000
--- a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/mediastream/url_media_stream.h"
-
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/frame/deprecation.h"
-#include "third_party/blink/renderer/core/url/dom_url.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-String URLMediaStream::createObjectURL(ScriptState* script_state,
- MediaStream* stream) {
- // Since WebWorkers cannot obtain Stream objects, we should be on the main
- // thread.
- DCHECK(IsMainThread());
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- DCHECK(execution_context);
- DCHECK(stream);
-
- Deprecation::CountDeprecation(execution_context,
- WebFeature::kCreateObjectURLMediaStream);
- return DOMURL::CreatePublicURL(execution_context, stream);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.h b/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.h
deleted file mode 100644
index 1cf630e7878..00000000000
--- a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_URL_MEDIA_STREAM_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_URL_MEDIA_STREAM_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-
-namespace blink {
-
-class MediaStream;
-class ScriptState;
-
-class URLMediaStream {
- STATIC_ONLY(URLMediaStream);
-
- public:
- static String createObjectURL(ScriptState*, MediaStream*);
-};
-
-} // namespace blink
-
-#endif
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.idl b/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.idl
deleted file mode 100644
index c7f8d34effe..00000000000
--- a/chromium/third_party/blink/renderer/modules/mediastream/url_media_stream.idl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// An old version of Media Capture and Streams defines URL.createObjectURL:
-// https://w3c.github.io/mediacapture-main/archives/20131017/getusermedia.html
-
-// TODO(foolip): Update link if it's revived in the spec:
-// https://github.com/w3c/mediacapture-main/issues/404
-
-[
- ImplementedAs=URLMediaStream
-] partial interface URL {
- [Exposed=(Window,DedicatedWorker,SharedWorker), CallWith=ScriptState] static DOMString createObjectURL(MediaStream stream);
-};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
index 68eb294ad3c..6096ec23ea6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc
@@ -69,4 +69,11 @@ void UserMediaClient::StopTrack(MediaStreamComponent* track) {
}
}
+bool UserMediaClient::IsCapturing() {
+ if (!client_)
+ return false;
+
+ return client_->IsCapturing();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
index 2eb60d43cec..9e9e943b5a0 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h
@@ -56,6 +56,7 @@ class MODULES_EXPORT UserMediaClient {
void CancelUserMediaRequest(UserMediaRequest*);
void ApplyConstraints(ApplyConstraintsRequest*);
void StopTrack(MediaStreamComponent*);
+ bool IsCapturing();
private:
explicit UserMediaClient(WebUserMediaClient*);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
index 03c2b2a3c38..06e0ae7b328 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -282,11 +282,6 @@ void CountVideoConstraintUses(ExecutionContext* context,
constraints, &WebMediaTrackConstraintSet::goog_noise_reduction)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogNoiseReduction);
}
- if (RequestUsesNumericConstraint(
- constraints,
- &WebMediaTrackConstraintSet::goog_power_line_frequency)) {
- counter.Count(WebFeature::kMediaStreamConstraintsGoogPowerLineFrequency);
- }
UseCounter::Count(context, WebFeature::kMediaStreamConstraintsVideo);
if (counter.IsUnconstrained()) {
@@ -497,17 +492,15 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
// Feature policy deprecation messages.
if (Audio()) {
- if (!document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kMicrophone,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kMicrophone,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(
document, WebFeature::kMicrophoneDisabledByFeaturePolicyEstimate);
}
}
if (Video()) {
- if (!document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kCamera,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kCamera,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document,
WebFeature::kCameraDisabledByFeaturePolicyEstimate);
}
@@ -530,11 +523,7 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
}
Document* UserMediaRequest::OwnerDocument() {
- if (ExecutionContext* context = GetExecutionContext()) {
- return ToDocument(context);
- }
-
- return nullptr;
+ return To<Document>(GetExecutionContext());
}
void UserMediaRequest::Start() {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl b/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
index 63c2c5937ef..ecb82580e6f 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
@@ -5,7 +5,7 @@
[
ImplementedAs=DOMWindowMediaStream
] partial interface Window {
- attribute MediaStreamConstructor webkitMediaStream;
+ [Measure] attribute MediaStreamConstructor webkitMediaStream;
- attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
+ [Measure] attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
};
diff --git a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
index 1b46d11ac4f..c97681e4079 100644
--- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -73,10 +73,11 @@ modules_idl_files =
"background_fetch/background_fetch_update_ui_event.idl",
"background_sync/sync_event.idl",
"background_sync/sync_manager.idl",
+ "badging/badge.idl",
"battery/battery_manager.idl",
"bluetooth/bluetooth.idl",
- "bluetooth/bluetooth_device.idl",
"bluetooth/bluetooth_characteristic_properties.idl",
+ "bluetooth/bluetooth_device.idl",
"bluetooth/bluetooth_remote_gatt_characteristic.idl",
"bluetooth/bluetooth_remote_gatt_descriptor.idl",
"bluetooth/bluetooth_remote_gatt_server.idl",
@@ -89,6 +90,8 @@ modules_idl_files =
"canvas/canvas2d/canvas_pattern.idl",
"canvas/canvas2d/canvas_rendering_context_2d.idl",
"canvas/canvas2d/path_2d.idl",
+ "canvas/imagebitmap/image_bitmap_rendering_context.idl",
+ "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
"clipboard/clipboard.idl",
"cookie_store/cookie_change_event.idl",
"cookie_store/cookie_store.idl",
@@ -112,7 +115,9 @@ modules_idl_files =
"device_orientation/device_orientation_event.idl",
"device_orientation/device_rotation_rate.idl",
"encoding/text_decoder.idl",
+ "encoding/text_decoder_stream.idl",
"encoding/text_encoder.idl",
+ "encoding/text_encoder_stream.idl",
"encryptedmedia/media_encrypted_event.idl",
"encryptedmedia/media_key_message_event.idl",
"encryptedmedia/media_key_session.idl",
@@ -120,12 +125,12 @@ modules_idl_files =
"encryptedmedia/media_key_system_access.idl",
"encryptedmedia/media_keys.idl",
"eventsource/event_source.idl",
- "filesystem/dom_file_system.idl",
- "filesystem/dom_file_system_sync.idl",
"filesystem/directory_entry.idl",
"filesystem/directory_entry_sync.idl",
"filesystem/directory_reader.idl",
"filesystem/directory_reader_sync.idl",
+ "filesystem/dom_file_system.idl",
+ "filesystem/dom_file_system_sync.idl",
"filesystem/entries_callback.idl",
"filesystem/entry.idl",
"filesystem/entry_callback.idl",
@@ -135,9 +140,10 @@ modules_idl_files =
"filesystem/file_entry.idl",
"filesystem/file_entry_sync.idl",
"filesystem/file_system_base_handle.idl",
+ "filesystem/file_system_callback.idl",
"filesystem/file_system_directory_handle.idl",
+ "filesystem/file_system_directory_iterator.idl",
"filesystem/file_system_file_handle.idl",
- "filesystem/file_system_callback.idl",
"filesystem/file_system_writer.idl",
"filesystem/file_writer.idl",
"filesystem/file_writer_callback.idl",
@@ -154,7 +160,6 @@ modules_idl_files =
"geolocation/geolocation.idl",
"geolocation/position.idl",
"geolocation/position_error.idl",
- "canvas/imagebitmap/image_bitmap_rendering_context.idl",
"imagecapture/image_capture.idl",
"imagecapture/media_settings_range.idl",
"imagecapture/photo_capabilities.idl",
@@ -165,9 +170,9 @@ modules_idl_files =
"indexeddb/idb_index.idl",
"indexeddb/idb_key_range.idl",
"indexeddb/idb_object_store.idl",
+ "indexeddb/idb_observation.idl",
"indexeddb/idb_observer.idl",
"indexeddb/idb_observer_changes.idl",
- "indexeddb/idb_observation.idl",
"indexeddb/idb_open_db_request.idl",
"indexeddb/idb_request.idl",
"indexeddb/idb_transaction.idl",
@@ -202,27 +207,28 @@ modules_idl_files =
"nfc/nfc.idl",
"notifications/notification.idl",
"notifications/notification_event.idl",
- "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
"payments/abort_payment_event.idl",
"payments/can_make_payment_event.idl",
"payments/payment_address.idl",
"payments/payment_instruments.idl",
"payments/payment_manager.idl",
+ "payments/payment_method_change_event.idl",
+ "payments/payment_request.idl",
"payments/payment_request_event.idl",
"payments/payment_request_update_event.idl",
- "payments/payment_request.idl",
"payments/payment_response.idl",
"peerconnection/rtc_certificate.idl",
- "peerconnection/rtc_dtmf_sender.idl",
- "peerconnection/rtc_dtmf_tone_change_event.idl",
"peerconnection/rtc_data_channel.idl",
"peerconnection/rtc_data_channel_event.idl",
+ "peerconnection/rtc_dtmf_sender.idl",
+ "peerconnection/rtc_dtmf_tone_change_event.idl",
"peerconnection/rtc_ice_candidate.idl",
"peerconnection/rtc_ice_transport.idl",
"peerconnection/rtc_legacy_stats_report.idl",
"peerconnection/rtc_peer_connection.idl",
"peerconnection/rtc_peer_connection_ice_event.idl",
"peerconnection/rtc_quic_stream.idl",
+ "peerconnection/rtc_quic_stream_event.idl",
"peerconnection/rtc_quic_transport.idl",
"peerconnection/rtc_rtp_contributing_source.idl",
"peerconnection/rtc_rtp_receiver.idl",
@@ -232,8 +238,8 @@ modules_idl_files =
"peerconnection/rtc_stats_report.idl",
"peerconnection/rtc_stats_response.idl",
"peerconnection/rtc_track_event.idl",
- "permissions/permissions.idl",
"permissions/permission_status.idl",
+ "permissions/permissions.idl",
"picture_in_picture/enter_picture_in_picture_event.idl",
"picture_in_picture/picture_in_picture_window.idl",
"plugins/mime_type.idl",
@@ -253,9 +259,9 @@ modules_idl_files =
"push_messaging/push_message_data.idl",
"push_messaging/push_subscription.idl",
"push_messaging/push_subscription_options.idl",
- "quota/dom_error.idl",
"quota/deprecated_storage_info.idl",
"quota/deprecated_storage_quota.idl",
+ "quota/dom_error.idl",
"quota/storage_manager.idl",
"remoteplayback/remote_playback.idl",
"screen_orientation/screen_orientation.idl",
@@ -269,6 +275,8 @@ modules_idl_files =
"sensor/relative_orientation_sensor.idl",
"sensor/sensor.idl",
"sensor/sensor_error_event.idl",
+ "serial/serial.idl",
+ "serial/serial_port.idl",
"service_worker/client.idl",
"service_worker/clients.idl",
"service_worker/extendable_event.idl",
@@ -296,14 +304,15 @@ modules_idl_files =
"speech/speech_recognition_result.idl",
"speech/speech_recognition_result_list.idl",
"speech/speech_synthesis.idl",
+ "speech/speech_synthesis_error_event.idl",
"speech/speech_synthesis_event.idl",
"speech/speech_synthesis_utterance.idl",
"speech/speech_synthesis_voice.idl",
"storage/storage.idl",
"storage/storage_event.idl",
"vr/vr_display.idl",
- "vr/vr_display_event.idl",
"vr/vr_display_capabilities.idl",
+ "vr/vr_display_event.idl",
"vr/vr_eye_parameters.idl",
"vr/vr_frame_data.idl",
"vr/vr_pose.idl",
@@ -323,8 +332,8 @@ modules_idl_files =
"webaudio/audio_scheduled_source_node.idl",
"webaudio/audio_worklet.idl",
"webaudio/audio_worklet_global_scope.idl",
- "webaudio/audio_worklet_processor.idl",
"webaudio/audio_worklet_node.idl",
+ "webaudio/audio_worklet_processor.idl",
"webaudio/base_audio_context.idl",
"webaudio/biquad_filter_node.idl",
"webaudio/channel_merger_node.idl",
@@ -363,8 +372,9 @@ modules_idl_files =
"webgl/ext_disjoint_timer_query_webgl2.idl",
"webgl/ext_frag_depth.idl",
"webgl/ext_shader_texture_lod.idl",
- "webgl/ext_texture_filter_anisotropic.idl",
"webgl/ext_srgb.idl",
+ "webgl/ext_texture_filter_anisotropic.idl",
+ "webgl/khr_parallel_shader_compile.idl",
"webgl/oes_element_index_uint.idl",
"webgl/oes_standard_derivatives.idl",
"webgl/oes_texture_float.idl",
@@ -419,10 +429,10 @@ modules_idl_files =
"websockets/websocket.idl",
"webusb/usb.idl",
"webusb/usb_alternate_interface.idl",
- "webusb/usb_endpoint.idl",
"webusb/usb_configuration.idl",
"webusb/usb_connection_event.idl",
"webusb/usb_device.idl",
+ "webusb/usb_endpoint.idl",
"webusb/usb_in_transfer_result.idl",
"webusb/usb_interface.idl",
"webusb/usb_isochronous_in_transfer_packet.idl",
@@ -459,8 +469,8 @@ if (support_webgl2_compute_context) {
modules_callback_function_idl_files =
get_path_info([
- "xr/xr_frame_request_callback.idl",
"quota/deprecated_storage_callbacks.idl",
+ "xr/xr_frame_request_callback.idl",
],
"abspath")
@@ -483,8 +493,8 @@ modules_dictionary_idl_files =
"cookie_store/cookie_list_item.idl",
"cookie_store/cookie_store_delete_options.idl",
"cookie_store/cookie_store_get_options.idl",
- "cookie_store/cookie_store_set_options.idl",
"cookie_store/cookie_store_set_extra_options.idl",
+ "cookie_store/cookie_store_set_options.idl",
"cookie_store/extendable_cookie_change_event_init.idl",
"credentialmanager/authentication_extensions_client_inputs.idl",
"credentialmanager/authentication_extensions_client_outputs.idl",
@@ -513,18 +523,24 @@ modules_dictionary_idl_files =
"encoding/text_decode_options.idl",
"encoding/text_decoder_options.idl",
"encryptedmedia/media_encrypted_event_init.idl",
- "encryptedmedia/media_keys_policy.idl",
"encryptedmedia/media_key_message_event_init.idl",
"encryptedmedia/media_key_system_configuration.idl",
"encryptedmedia/media_key_system_media_capability.idl",
+ "encryptedmedia/media_keys_policy.idl",
"eventsource/event_source_init.idl",
+ "filesystem/choose_file_system_entries_options.idl",
+ "filesystem/choose_file_system_entries_options_accepts.idl",
+ "filesystem/file_system_directory_iterator_entry.idl",
"filesystem/file_system_flags.idl",
+ "filesystem/file_system_get_directory_options.idl",
+ "filesystem/file_system_get_file_options.idl",
+ "filesystem/get_system_directory_options.idl",
"gamepad/gamepad_effect_parameters.idl",
"gamepad/gamepad_event_init.idl",
"geolocation/position_options.idl",
"imagecapture/constrain_point_2d_parameters.idl",
- "imagecapture/point_2d.idl",
"imagecapture/photo_settings.idl",
+ "imagecapture/point_2d.idl",
"indexeddb/idb_index_parameters.idl",
"indexeddb/idb_object_store_parameters.idl",
"indexeddb/idb_observer_init.idl",
@@ -570,27 +586,28 @@ modules_dictionary_idl_files =
"payments/basic_card_request.idl",
"payments/can_make_payment_event_init.idl",
"payments/image_object.idl",
- "payments/payer_error_fields.idl",
- "payments/payment_handler_response.idl",
- "payments/payment_request_event_init.idl",
+ "payments/payer_errors.idl",
"payments/payment_currency_amount.idl",
"payments/payment_details_base.idl",
"payments/payment_details_init.idl",
"payments/payment_details_modifier.idl",
"payments/payment_details_update.idl",
+ "payments/payment_handler_response.idl",
+ "payments/payment_instrument.idl",
"payments/payment_item.idl",
+ "payments/payment_method_change_event_init.idl",
"payments/payment_method_data.idl",
"payments/payment_options.idl",
- "payments/payment_instrument.idl",
+ "payments/payment_request_event_init.idl",
"payments/payment_request_update_event_init.idl",
"payments/payment_shipping_option.idl",
"payments/payment_validation_errors.idl",
"peerconnection/rtc_answer_options.idl",
"peerconnection/rtc_configuration.idl",
"peerconnection/rtc_data_channel_event_init.idl",
+ "peerconnection/rtc_data_channel_init.idl",
"peerconnection/rtc_dtls_fingerprint.idl",
"peerconnection/rtc_dtmf_tone_change_event_init.idl",
- "peerconnection/rtc_data_channel_init.idl",
"peerconnection/rtc_ice_candidate_init.idl",
"peerconnection/rtc_ice_candidate_pair.idl",
"peerconnection/rtc_ice_gather_options.idl",
@@ -600,6 +617,7 @@ modules_dictionary_idl_files =
"peerconnection/rtc_offer_options.idl",
"peerconnection/rtc_peer_connection_ice_event_init.idl",
"peerconnection/rtc_quic_parameters.idl",
+ "peerconnection/rtc_quic_stream_event_init.idl",
"peerconnection/rtc_rtcp_parameters.idl",
"peerconnection/rtc_rtp_capabilities.idl",
"peerconnection/rtc_rtp_codec_capability.idl",
@@ -609,8 +627,8 @@ modules_dictionary_idl_files =
"peerconnection/rtc_rtp_header_extension_capability.idl",
"peerconnection/rtc_rtp_header_extension_parameters.idl",
"peerconnection/rtc_rtp_parameters.idl",
- "peerconnection/rtc_rtp_transceiver_init.idl",
"peerconnection/rtc_rtp_send_parameters.idl",
+ "peerconnection/rtc_rtp_transceiver_init.idl",
"peerconnection/rtc_session_description_init.idl",
"peerconnection/rtc_track_event_init.idl",
"permissions/clipboard_permission_descriptor.idl",
@@ -627,6 +645,8 @@ modules_dictionary_idl_files =
"sensor/sensor_error_event_init.idl",
"sensor/sensor_options.idl",
"sensor/spatial_sensor_options.idl",
+ "serial/serial_options.idl",
+ "serial/serial_port_request_options.idl",
"service_worker/client_query_options.idl",
"service_worker/extendable_event_init.idl",
"service_worker/extendable_message_event_init.idl",
@@ -637,6 +657,8 @@ modules_dictionary_idl_files =
"shapedetection/landmark.idl",
"speech/speech_recognition_error_init.idl",
"speech/speech_recognition_event_init.idl",
+ "speech/speech_synthesis_error_event_init.idl",
+ "speech/speech_synthesis_event_init.idl",
"storage/storage_event_init.idl",
"vr/vr_display_event_init.idl",
"vr/vr_layer_init.idl",
@@ -645,10 +667,10 @@ modules_dictionary_idl_files =
"webaudio/audio_buffer_source_options.idl",
"webaudio/audio_context_options.idl",
"webaudio/audio_node_options.idl",
- "webaudio/audio_worklet_node_options.idl",
"webaudio/audio_param_descriptor.idl",
"webaudio/audio_processing_event_init.idl",
"webaudio/audio_timestamp.idl",
+ "webaudio/audio_worklet_node_options.idl",
"webaudio/biquad_filter_options.idl",
"webaudio/channel_merger_options.idl",
"webaudio/channel_splitter_options.idl",
@@ -660,12 +682,12 @@ modules_dictionary_idl_files =
"webaudio/iir_filter_options.idl",
"webaudio/media_element_audio_source_options.idl",
"webaudio/media_stream_audio_source_options.idl",
+ "webaudio/offline_audio_completion_event_init.idl",
+ "webaudio/offline_audio_context_options.idl",
+ "webaudio/oscillator_options.idl",
"webaudio/panner_options.idl",
"webaudio/periodic_wave_constraints.idl",
"webaudio/periodic_wave_options.idl",
- "webaudio/oscillator_options.idl",
- "webaudio/offline_audio_completion_event_init.idl",
- "webaudio/offline_audio_context_options.idl",
"webaudio/stereo_panner_options.idl",
"webaudio/wave_shaper_options.idl",
"webgl/webgl_context_attributes.idl",
@@ -738,19 +760,18 @@ modules_dependency_idl_files =
"mediacapturefromelement/html_media_element_capture.idl",
"mediasession/navigator_media_session.idl",
"mediasource/audio_track_source_buffer.idl",
- "mediasource/video_track_source_buffer.idl",
"mediasource/html_video_element_media_source.idl",
"mediasource/url_media_source.idl",
+ "mediasource/video_track_source_buffer.idl",
"mediastream/media_stream_track_content_hint.idl",
"mediastream/navigator_display_media.idl",
"mediastream/navigator_media_stream.idl",
"mediastream/navigator_user_media.idl",
- "mediastream/url_media_stream.idl",
"mediastream/window_media_stream.idl",
"navigatorcontentutils/navigator_content_utils.idl",
- "nfc/navigator_nfc.idl",
"netinfo/navigator_network_information.idl",
"netinfo/worker_navigator_network_information.idl",
+ "nfc/navigator_nfc.idl",
"notifications/service_worker_global_scope_notifications.idl",
"notifications/service_worker_registration_notifications.idl",
"payments/html_iframe_element_payments.idl",
@@ -770,6 +791,8 @@ modules_dependency_idl_files =
"quota/worker_navigator_storage_quota.idl",
"remoteplayback/html_media_element_remote_playback.idl",
"screen_orientation/screen_screen_orientation.idl",
+ "serial/navigator_serial.idl",
+ "serial/worker_navigator_serial.idl",
"service_worker/navigator_service_worker.idl",
"speech/window_speech.idl",
"speech/window_speech_synthesis.idl",
diff --git a/chromium/third_party/blink/renderer/modules/modules_initializer.cc b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
index b62523ddaf3..82b006bfe0f 100644
--- a/chromium/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
@@ -75,7 +75,7 @@
#include "third_party/blink/renderer/modules/speech/speech_recognition_controller.h"
#include "third_party/blink/renderer/modules/storage/dom_window_storage_controller.h"
#include "third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h"
-#include "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
+#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
#include "third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.h"
#include "third_party/blink/renderer/modules/vr/navigator_vr.h"
#include "third_party/blink/renderer/modules/vr/vr_controller.h"
@@ -225,7 +225,7 @@ void ModulesInitializer::InitInspectorAgentSession(
session->Append(new InspectorDOMStorageAgent(inspected_frames));
if (allow_view_agents) {
session->Append(InspectorDatabaseAgent::Create(page));
- session->Append(new InspectorAccessibilityAgent(page, dom_agent));
+ session->Append(new InspectorAccessibilityAgent(inspected_frames, dom_agent));
session->Append(InspectorCacheStorageAgent::Create(inspected_frames));
}
}
@@ -274,7 +274,7 @@ void ModulesInitializer::ProvideModulesToPage(Page& page,
MediaKeysController::ProvideMediaKeysTo(page);
::blink::ProvideContextFeaturesTo(page, ContextFeaturesClientImpl::Create());
::blink::ProvideDatabaseClientTo(page, new DatabaseClient);
- StorageNamespaceController::ProvideStorageNamespaceTo(page, client);
+ StorageNamespace::ProvideSessionStorageNamespaceTo(page, client);
}
void ModulesInitializer::ForceNextWebGLContextCreationToFail() const {
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
index 587fae6bbbc..e62eb4a998d 100644
--- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
index 127db758e76..7597be853ed 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
@@ -11,6 +11,8 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/inspector/console_types.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -23,10 +25,10 @@ Settings* GetSettings(ExecutionContext* execution_context) {
if (!execution_context)
return nullptr;
- if (!execution_context->IsDocument())
+ auto* document = DynamicTo<Document>(execution_context);
+ if (!document)
return nullptr;
- Document* document = ToDocument(execution_context);
// |document| is guaranteed to be non-null since |execution_context| is
// non-null.
return document->GetSettings();
@@ -64,6 +66,11 @@ String ConnectionTypeToString(WebConnectionType type) {
return "none";
}
+String GetConsoleLogStringForWebHoldback() {
+ return "Network quality values are overridden using a holdback experiment, "
+ "and so may be inaccurate";
+}
+
} // namespace
NetworkInformation* NetworkInformation::Create(ExecutionContext* context) {
@@ -95,7 +102,15 @@ double NetworkInformation::downlinkMax() const {
return downlink_max_mbps_;
}
-String NetworkInformation::effectiveType() const {
+String NetworkInformation::effectiveType() {
+ MaybeShowWebHoldbackConsoleMsg();
+ base::Optional<WebEffectiveConnectionType> override_ect =
+ GetNetworkStateNotifier().GetWebHoldbackEffectiveType();
+ if (override_ect) {
+ return NetworkStateNotifier::EffectiveConnectionTypeToString(
+ override_ect.value());
+ }
+
// effective_type_ is only updated when listening for events, so ask
// networkStateNotifier if not listening (crbug.com/379841).
if (!IsObserving()) {
@@ -107,7 +122,14 @@ String NetworkInformation::effectiveType() const {
return NetworkStateNotifier::EffectiveConnectionTypeToString(effective_type_);
}
-unsigned long NetworkInformation::rtt() const {
+unsigned long NetworkInformation::rtt() {
+ MaybeShowWebHoldbackConsoleMsg();
+ base::Optional<TimeDelta> override_rtt =
+ GetNetworkStateNotifier().GetWebHoldbackHttpRtt();
+ if (override_rtt) {
+ return GetNetworkStateNotifier().RoundRtt(Host(), override_rtt.value());
+ }
+
if (!IsObserving()) {
return GetNetworkStateNotifier().RoundRtt(
Host(), GetNetworkStateNotifier().HttpRtt());
@@ -116,7 +138,15 @@ unsigned long NetworkInformation::rtt() const {
return http_rtt_msec_;
}
-double NetworkInformation::downlink() const {
+double NetworkInformation::downlink() {
+ MaybeShowWebHoldbackConsoleMsg();
+ base::Optional<double> override_downlink_mbps =
+ GetNetworkStateNotifier().GetWebHoldbackDownlinkThroughputMbps();
+ if (override_downlink_mbps) {
+ return GetNetworkStateNotifier().RoundMbps(Host(),
+ override_downlink_mbps.value());
+ }
+
if (!IsObserving()) {
return GetNetworkStateNotifier().RoundMbps(
Host(), GetNetworkStateNotifier().DownlinkThroughputMbps());
@@ -148,20 +178,27 @@ void NetworkInformation::ConnectionChange(
double new_downlink_mbps =
GetNetworkStateNotifier().RoundMbps(host, downlink_mbps);
+ bool network_quality_estimate_changed = false;
+ // Allow setting |network_quality_estimate_changed| to true only if the
+ // network quality holdback experiment is not enabled.
+ if (!GetNetworkStateNotifier().GetWebHoldbackEffectiveType()) {
+ network_quality_estimate_changed = effective_type_ != effective_type ||
+ http_rtt_msec_ != new_http_rtt_msec ||
+ downlink_mbps_ != new_downlink_mbps;
+ }
+
// This can happen if the observer removes and then adds itself again
// during notification, or if |transport_rtt| was the only metric that
// changed.
if (type_ == type && downlink_max_mbps_ == downlink_max_mbps &&
- effective_type_ == effective_type &&
- http_rtt_msec_ == new_http_rtt_msec &&
- downlink_mbps_ == new_downlink_mbps && save_data_ == save_data) {
+ !network_quality_estimate_changed && save_data_ == save_data) {
return;
}
+ // If the NetInfoDownlinkMaxEnabled is not enabled, then |type| and
+ // |downlink_max_mbps| should not be checked for change.
if (!RuntimeEnabledFeatures::NetInfoDownlinkMaxEnabled() &&
- effective_type_ == effective_type &&
- http_rtt_msec_ == new_http_rtt_msec &&
- downlink_mbps_ == new_downlink_mbps && save_data_ == save_data) {
+ !network_quality_estimate_changed && save_data_ == save_data) {
return;
}
@@ -171,9 +208,11 @@ void NetworkInformation::ConnectionChange(
type_ = type;
downlink_max_mbps_ = downlink_max_mbps;
- effective_type_ = effective_type;
- http_rtt_msec_ = new_http_rtt_msec;
- downlink_mbps_ = new_downlink_mbps;
+ if (network_quality_estimate_changed) {
+ effective_type_ = effective_type;
+ http_rtt_msec_ = new_http_rtt_msec;
+ downlink_mbps_ = new_downlink_mbps;
+ }
save_data_ = save_data;
if (type_changed)
@@ -194,6 +233,7 @@ void NetworkInformation::AddedEventListener(
RegisteredEventListener& registered_listener) {
EventTargetWithInlineData::AddedEventListener(event_type,
registered_listener);
+ MaybeShowWebHoldbackConsoleMsg();
StartObserving();
}
@@ -243,18 +283,20 @@ void NetworkInformation::StopObserving() {
NetworkInformation::NetworkInformation(ExecutionContext* context)
: ContextLifecycleObserver(context),
- type_(GetNetworkStateNotifier().ConnectionType()),
- downlink_max_mbps_(GetNetworkStateNotifier().MaxBandwidth()),
- effective_type_(GetNetworkStateNotifier().EffectiveType()),
- http_rtt_msec_(GetNetworkStateNotifier().RoundRtt(
- Host(),
- GetNetworkStateNotifier().HttpRtt())),
- downlink_mbps_(GetNetworkStateNotifier().RoundMbps(
- Host(),
- GetNetworkStateNotifier().DownlinkThroughputMbps())),
- save_data_(GetNetworkStateNotifier().SaveDataEnabled() &&
- !IsInDataSaverHoldbackWebApi(GetExecutionContext())),
+ web_holdback_console_message_shown_(false),
context_stopped_(false) {
+ base::Optional<TimeDelta> http_rtt;
+ base::Optional<double> downlink_mbps;
+
+ GetNetworkStateNotifier().GetMetricsWithWebHoldback(
+ &type_, &downlink_max_mbps_, &effective_type_, &http_rtt, &downlink_mbps,
+ &save_data_);
+
+ http_rtt_msec_ = GetNetworkStateNotifier().RoundRtt(Host(), http_rtt);
+ downlink_mbps_ = GetNetworkStateNotifier().RoundMbps(Host(), downlink_mbps);
+ save_data_ =
+ save_data_ && !IsInDataSaverHoldbackWebApi(GetExecutionContext());
+
DCHECK_LE(1u, GetNetworkStateNotifier().RandomizationSalt());
DCHECK_GE(20u, GetNetworkStateNotifier().RandomizationSalt());
}
@@ -268,4 +310,15 @@ const String NetworkInformation::Host() const {
return GetExecutionContext() ? GetExecutionContext()->Url().Host() : String();
}
+void NetworkInformation::MaybeShowWebHoldbackConsoleMsg() {
+ if (web_holdback_console_message_shown_)
+ return;
+ web_holdback_console_message_shown_ = true;
+ if (!GetNetworkStateNotifier().GetWebHoldbackEffectiveType())
+ return;
+ GetExecutionContext()->AddConsoleMessage(
+ ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel,
+ GetConsoleLogStringForWebHoldback()));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
index 5af8102fbe6..b8170e43fcd 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
@@ -32,9 +32,9 @@ class NetworkInformation final
String type() const;
double downlinkMax() const;
- String effectiveType() const;
- unsigned long rtt() const;
- double downlink() const;
+ String effectiveType();
+ unsigned long rtt();
+ double downlink();
bool saveData() const;
// NetworkStateObserver overrides.
@@ -79,6 +79,8 @@ class NetworkInformation final
const String Host() const;
+ void MaybeShowWebHoldbackConsoleMsg();
+
// Touched only on context thread.
WebConnectionType type_;
@@ -101,6 +103,11 @@ class NetworkInformation final
// Whether the data saving mode is enabled.
bool save_data_;
+ // True if the console message indicating that network quality is overridden
+ // using a holdback experiment has been shown. Set to true if the console
+ // message has been shown, or if the holdback experiment is not enabled.
+ bool web_holdback_console_message_shown_;
+
// Whether ContextLifecycleObserver::contextDestroyed has been called.
bool context_stopped_;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/OWNERS b/chromium/third_party/blink/renderer/modules/nfc/OWNERS
index 24ac3f7fea7..0243a40c25d 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/nfc/OWNERS
@@ -1,3 +1,2 @@
-alexander.shalamov@intel.com
kenneth.r.christiansen@intel.com
-rijubrata.bhaumik@intel.com \ No newline at end of file
+rijubrata.bhaumik@intel.com
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc.cc
index e86dbe865b6..282d7b54c03 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/modules/nfc/nfc_push_options.h"
#include "third_party/blink/renderer/modules/nfc/nfc_watch_options.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace {
const char kJsonMimePostfix[] = "+json";
@@ -269,7 +270,7 @@ struct TypeConverter<NFCMessagePtr, blink::NFCMessage> {
NFCMessagePtr messagePtr = NFCMessage::New();
messagePtr->url = message.url();
messagePtr->data.resize(message.records().size());
- for (size_t i = 0; i < message.records().size(); ++i) {
+ for (wtf_size_t i = 0; i < message.records().size(); ++i) {
NFCRecordPtr record = NFCRecord::From(message.records()[i]);
if (record.is_null())
return nullptr;
@@ -618,7 +619,7 @@ NFCMessage ToNFCMessage(ScriptState* script_state,
NFCMessage nfc_message;
nfc_message.setURL(message->url);
blink::HeapVector<NFCRecord> records;
- for (size_t i = 0; i < message->data.size(); ++i)
+ for (wtf_size_t i = 0; i < message->data.size(); ++i)
records.push_back(ToNFCRecord(script_state, message->data[i]));
nfc_message.setRecords(records);
return nfc_message;
@@ -626,7 +627,7 @@ NFCMessage ToNFCMessage(ScriptState* script_state,
size_t GetNFCMessageSize(const device::mojom::blink::NFCMessagePtr& message) {
size_t message_size = message->url.CharactersSizeInBytes();
- for (size_t i = 0; i < message->data.size(); ++i) {
+ for (wtf_size_t i = 0; i < message->data.size(); ++i) {
message_size += message->data[i]->media_type.CharactersSizeInBytes();
message_size += message->data[i]->data.size();
}
@@ -774,7 +775,7 @@ ScriptPromise NFC::watch(ScriptState* script_state,
}
// https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch
-ScriptPromise NFC::cancelWatch(ScriptState* script_state, long id) {
+ScriptPromise NFC::cancelWatch(ScriptState* script_state, int32_t id) {
ScriptPromise promise = RejectIfNotSupported(script_state);
if (!promise.IsEmpty())
return promise;
@@ -871,8 +872,8 @@ bool NFC::IsSupportedInContext(ExecutionContext* context,
String& error_message) {
// https://w3c.github.io/web-nfc/#security-policies
// WebNFC API must be only accessible from top level browsing context.
- if (!ToDocument(context)->domWindow()->GetFrame() ||
- !ToDocument(context)->GetFrame()->IsMainFrame()) {
+ if (!To<Document>(context)->domWindow()->GetFrame() ||
+ !To<Document>(context)->GetFrame()->IsMainFrame()) {
error_message = "Must be in a top-level browsing context";
return false;
}
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc.h b/chromium/third_party/blink/renderer/modules/nfc/nfc.h
index 393638048eb..554581deb53 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc.h
@@ -52,7 +52,7 @@ class NFC final : public ScriptWrappable,
ScriptPromise watch(ScriptState*, V8MessageCallback*, const NFCWatchOptions&);
// Cancels watch operation with id.
- ScriptPromise cancelWatch(ScriptState*, long id);
+ ScriptPromise cancelWatch(ScriptState*, int32_t id);
// Cancels all watch operations.
ScriptPromise cancelWatch(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
index 6e277ad9cba..ce2d4eb96d1 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
@@ -57,6 +57,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
@@ -86,19 +87,19 @@ Notification* Notification::Create(ExecutionContext* context,
return nullptr;
}
+ auto* document = DynamicTo<Document>(context);
if (context->IsSecureContext()) {
UseCounter::Count(context, WebFeature::kNotificationSecureOrigin);
- if (context->IsDocument()) {
+ if (document) {
UseCounter::CountCrossOriginIframe(
- *ToDocument(context), WebFeature::kNotificationAPISecureOriginIframe);
+ *document, WebFeature::kNotificationAPISecureOriginIframe);
}
} else {
Deprecation::CountDeprecation(context,
WebFeature::kNotificationInsecureOrigin);
- if (context->IsDocument()) {
+ if (document) {
Deprecation::CountDeprecationCrossOriginIframe(
- *ToDocument(context),
- WebFeature::kNotificationAPIInsecureOriginIframe);
+ *document, WebFeature::kNotificationAPIInsecureOriginIframe);
}
}
@@ -126,7 +127,6 @@ Notification* Notification::Create(ExecutionContext* context,
notification->SchedulePrepareShow();
- Document* document = context->IsDocument() ? ToDocument(context) : nullptr;
if (document && document->GetFrame()) {
if (auto* frame_resource_coordinator =
document->GetFrame()->GetFrameResourceCoordinator()) {
@@ -229,10 +229,11 @@ void Notification::OnShow() {
void Notification::OnClick(OnClickCallback completed_closure) {
ExecutionContext* context = GetExecutionContext();
- Document* document = context->IsDocument() ? ToDocument(context) : nullptr;
+ Document* document = DynamicTo<Document>(context);
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(document ? document->GetFrame() : nullptr,
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(
+ document ? document->GetFrame() : nullptr,
+ UserGestureToken::kNewGesture);
ScopedWindowFocusAllowedIndicator window_focus_allowed(GetExecutionContext());
DispatchEvent(*Event::Create(EventTypeNames::click));
@@ -345,7 +346,7 @@ Vector<v8::Local<v8::Value>> Notification::actions(
const Vector<mojom::blink::NotificationActionPtr>& actions =
data_->actions.value();
result.Grow(actions.size());
- for (size_t i = 0; i < actions.size(); ++i) {
+ for (wtf_size_t i = 0; i < actions.size(); ++i) {
NotificationAction action;
switch (actions[i]->type) {
@@ -402,8 +403,9 @@ String Notification::permission(ExecutionContext* context) {
//
// TODO(crbug.com/758603): Move this check to the browser process when the
// NotificationService connection becomes frame-bound.
- if (status == mojom::blink::PermissionStatus::ASK && context->IsDocument()) {
- LocalFrame* frame = ToDocument(context)->GetFrame();
+ if (status == mojom::blink::PermissionStatus::ASK) {
+ auto* document = DynamicTo<Document>(context);
+ LocalFrame* frame = document ? document->GetFrame() : nullptr;
if (!frame || frame->IsCrossOriginSubframe())
status = mojom::blink::PermissionStatus::DENIED;
}
@@ -415,10 +417,11 @@ ScriptPromise Notification::requestPermission(
ScriptState* script_state,
V8NotificationPermissionCallback* deprecated_callback) {
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = DynamicTo<Document>(context);
probe::breakableLocation(context, "Notification.requestPermission");
- if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ if (!LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
+ : nullptr)) {
PerformanceMonitor::ReportGenericViolation(
context, PerformanceMonitor::kDiscouragedAPIUse,
"Only request notification permission in response to a user gesture.",
@@ -433,8 +436,8 @@ ScriptPromise Notification::requestPermission(
// Sites cannot request notification permission from cross-origin iframes,
// but they can use notifications if permission had already been granted.
- if (context->IsDocument()) {
- LocalFrame* frame = ToDocument(context)->GetFrame();
+ if (auto* document = DynamicTo<Document>(context)) {
+ LocalFrame* frame = document->GetFrame();
if (!frame || frame->IsCrossOriginSubframe()) {
Deprecation::CountDeprecation(
context, WebFeature::kNotificationPermissionRequestedIframe);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
index 76675044019..4e22ec98d17 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/vibration/vibration_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -100,7 +101,7 @@ mojom::blink::NotificationDataPtr CreateNotificationData(
notification_data->data = Vector<uint8_t>();
notification_data->data->Append(
serialized_script_value->Data(),
- serialized_script_value->DataLengthInBytes());
+ SafeCast<wtf_size_t>(serialized_script_value->DataLengthInBytes()));
}
Vector<mojom::blink::NotificationActionPtr> actions;
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data.h b/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
index 0dcb0f0228b..2e21e5b5fbe 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_DATA_H_
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
+#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
index edd59252eee..24296339e3d 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc
@@ -134,7 +134,7 @@ TEST_F(NotificationDataTest, ReflectProperties) {
ASSERT_EQ(vibration_pattern.size(),
notification_data->vibration_pattern->size());
- for (size_t i = 0; i < vibration_pattern.size(); ++i) {
+ for (wtf_size_t i = 0; i < vibration_pattern.size(); ++i) {
EXPECT_EQ(
vibration_pattern[i],
static_cast<unsigned>(notification_data->vibration_pattern.value()[i]));
@@ -259,7 +259,7 @@ TEST_F(NotificationDataTest, VibrationNormalization) {
ASSERT_EQ(normalized_pattern.size(),
notification_data->vibration_pattern->size());
- for (size_t i = 0; i < normalized_pattern.size(); ++i) {
+ for (wtf_size_t i = 0; i < normalized_pattern.size(); ++i) {
EXPECT_EQ(normalized_pattern[i],
notification_data->vibration_pattern.value()[i]);
}
@@ -323,7 +323,7 @@ TEST_F(NotificationDataTest, MaximumActionCount) {
// The stored actions will be capped to |maxActions| entries.
ASSERT_EQ(Notification::maxActions(), notification_data->actions->size());
- for (size_t i = 0; i < Notification::maxActions(); ++i) {
+ for (wtf_size_t i = 0; i < Notification::maxActions(); ++i) {
String expected_action = String::Number(i);
EXPECT_EQ(expected_action, notification_data->actions.value()[i]->action);
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
index fffba5f48a7..efe063638b4 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
@@ -113,9 +113,8 @@ void NotificationImageLoader::Start(ExecutionContext* context,
resource_loader_options.request_initiator_context = kWorkerContext;
ResourceRequest resource_request(url);
- resource_request.SetRequestContext(WebURLRequest::kRequestContextImage);
+ resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
resource_request.SetPriority(ResourceLoadPriority::kMedium);
- resource_request.SetRequestorOrigin(context->GetSecurityOrigin());
threadable_loader_ = new ThreadableLoader(
*context, this, resource_loader_options);
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
index 21d3be41d51..36bc76a3af6 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/modules/notifications/notification_manager.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/platform/interface_provider.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
@@ -79,10 +79,10 @@ ScriptPromise NotificationManager::RequestPermission(
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = DynamicTo<Document>(context);
permission_service_->RequestPermission(
CreatePermissionDescriptor(mojom::blink::PermissionName::NOTIFICATIONS),
- Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
+ LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
WTF::Bind(
&NotificationManager::OnPermissionRequestComplete,
WrapPersistent(this), WrapPersistent(resolver),
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
index 9e861a7858d..8bc1348277f 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/notifications/notification_resources_loader.h"
#include <cmath>
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
index f9b3e5fa784..1e8eb32074b 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_RESOURCES_LOADER_H_
#include <memory>
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
+#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/notifications/notification_image_loader.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
index 4af07fde36b..38c1ad06f17 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h
@@ -7,7 +7,7 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
+#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/BUILD.gn b/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
index 50bd846f9e7..ec0f2d75820 100644
--- a/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
@@ -31,6 +31,8 @@ blink_modules_sources("payments") {
"payment_instruments.h",
"payment_manager.cc",
"payment_manager.h",
+ "payment_method_change_event.cc",
+ "payment_method_change_event.h",
"payment_request.cc",
"payment_request.h",
"payment_request_event.cc",
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
index 7d563b26b3c..106793d6bd2 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc
@@ -10,7 +10,6 @@
#include "third_party/blink/renderer/core/workers/worker_location.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc b/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
index 28d762d6593..dc139e1e201 100644
--- a/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
@@ -78,7 +78,7 @@ TEST(OnPaymentResponseTest, RejectMissingName) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -100,7 +100,7 @@ TEST(OnPaymentResponseTest, RejectMissingEmail) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -122,7 +122,7 @@ TEST(OnPaymentResponseTest, RejectMissingPhone) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -195,8 +195,8 @@ TEST(OnPaymentResponseTest, RejectEmptyName) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_name = "";
+ BuildPaymentResponseForTest();
+ response->payer->name = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -218,8 +218,8 @@ TEST(OnPaymentResponseTest, RejectEmptyEmail) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_email = "";
+ BuildPaymentResponseForTest();
+ response->payer->email = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -241,8 +241,8 @@ TEST(OnPaymentResponseTest, RejectEmptyPhone) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_phone = "";
+ BuildPaymentResponseForTest();
+ response->payer->phone = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -264,7 +264,7 @@ TEST(OnPaymentResponseTest, RejectNotRequestedAddress) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
ASSERT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "US";
response->shipping_address->language_code = "en";
@@ -290,7 +290,7 @@ TEST(OnPaymentResponseTest, RejectNotRequestedShippingOption) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
ASSERT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
response->shipping_option = "";
request->show(scope.GetScriptState())
@@ -313,8 +313,8 @@ TEST(OnPaymentResponseTest, RejectNotRequestedName) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_name = "";
+ BuildPaymentResponseForTest();
+ response->payer->name = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -336,8 +336,8 @@ TEST(OnPaymentResponseTest, RejectNotRequestedEmail) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_email = "";
+ BuildPaymentResponseForTest();
+ response->payer->email = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -359,8 +359,8 @@ TEST(OnPaymentResponseTest, RejectNotRequestedPhone) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_phone = "";
+ BuildPaymentResponseForTest();
+ response->payer->phone = "";
request->show(scope.GetScriptState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -466,8 +466,9 @@ TEST(OnPaymentResponseTest, CanRequestName) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_name = "Jon Doe";
+ BuildPaymentResponseForTest();
+ response->payer = payments::mojom::blink::PayerDetail::New();
+ response->payer->name = "Jon Doe";
ScriptValue out_value;
request->show(scope.GetScriptState())
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
@@ -495,8 +496,8 @@ TEST(OnPaymentResponseTest, CanRequestEmail) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_email = "abc@gmail.com";
+ BuildPaymentResponseForTest();
+ response->payer->email = "abc@gmail.com";
ScriptValue out_value;
request->show(scope.GetScriptState())
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
@@ -524,8 +525,8 @@ TEST(OnPaymentResponseTest, CanRequestPhone) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_phone = "0123";
+ BuildPaymentResponseForTest();
+ response->payer->phone = "0123";
ScriptValue out_value;
request->show(scope.GetScriptState())
@@ -581,8 +582,8 @@ TEST(OnPaymentResponseTest, PhoneNotRequred) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_phone = String();
+ BuildPaymentResponseForTest();
+ response->payer->phone = String();
ScriptValue out_value;
request->show(scope.GetScriptState())
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
@@ -610,8 +611,8 @@ TEST(OnPaymentResponseTest, NameNotRequired) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_name = String();
+ BuildPaymentResponseForTest();
+ response->payer->name = String();
ScriptValue out_value;
request->show(scope.GetScriptState())
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
@@ -639,8 +640,8 @@ TEST(OnPaymentResponseTest, EmailNotRequired) {
BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
EXPECT_FALSE(scope.GetExceptionState().HadException());
payments::mojom::blink::PaymentResponsePtr response =
- payments::mojom::blink::PaymentResponse::New();
- response->payer_email = String();
+ BuildPaymentResponseForTest();
+ response->payer->email = String();
ScriptValue out_value;
request->show(scope.GetScriptState())
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
diff --git a/chromium/third_party/blink/renderer/modules/payments/payer_error_fields.idl b/chromium/third_party/blink/renderer/modules/payments/payer_errors.idl
index a56a8892749..5598afa6d68 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payer_error_fields.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payer_errors.idl
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/payment-request/#payererrorfields-dictionary
+// https://w3c.github.io/payment-request/#payererrors-dictionary
-dictionary PayerErrorFields {
+dictionary PayerErrors {
DOMString email;
DOMString name;
DOMString phone;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address.idl b/chromium/third_party/blink/renderer/modules/payments/payment_address.idl
index 74bda4207e3..58901857b34 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_address.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_address.idl
@@ -13,7 +13,7 @@
readonly attribute DOMString city;
readonly attribute DOMString country;
readonly attribute DOMString dependentLocality;
- readonly attribute DOMString languageCode;
+ [MeasureAs=PaymentAddressLanguageCode] readonly attribute DOMString languageCode;
readonly attribute DOMString organization;
readonly attribute DOMString phone;
readonly attribute DOMString postalCode;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_details_update.idl b/chromium/third_party/blink/renderer/modules/payments/payment_details_update.idl
index 73d0fcd66f4..7d798eb5d07 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_details_update.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_details_update.idl
@@ -7,4 +7,5 @@
dictionary PaymentDetailsUpdate : PaymentDetailsBase {
DOMString error;
PaymentItem total;
+ AddressErrors shippingAddressErrors;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 3c0e57ec11f..c452409fdbf 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -242,7 +242,7 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = DynamicTo<Document>(context);
// Should move this permission check to browser process.
// Please see http://crbug.com/795929
@@ -250,7 +250,8 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
->RequestPermission(
CreatePermissionDescriptor(
mojom::blink::PermissionName::PAYMENT_HANDLER),
- Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
+ LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
+ : nullptr),
WTF::Bind(&PaymentInstruments::OnRequestPermission,
WrapPersistent(this), WrapPersistent(resolver),
instrument_key,
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
new file mode 100644
index 00000000000..7d47a1040c7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/payments/payment_method_change_event.h"
+
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+
+namespace blink {
+
+PaymentMethodChangeEvent::~PaymentMethodChangeEvent() = default;
+
+// static
+PaymentMethodChangeEvent* PaymentMethodChangeEvent::Create(
+ ScriptState* script_state,
+ const AtomicString& type,
+ const PaymentMethodChangeEventInit& init) {
+ return new PaymentMethodChangeEvent(script_state, type, init);
+}
+
+const String& PaymentMethodChangeEvent::methodName() const {
+ return method_name_;
+}
+
+const ScriptValue PaymentMethodChangeEvent::methodDetails(
+ ScriptState* script_state) const {
+ return ScriptValue(script_state, method_details_.V8ValueFor(script_state));
+}
+
+PaymentMethodChangeEvent::PaymentMethodChangeEvent(
+ ScriptState* script_state,
+ const AtomicString& type,
+ const PaymentMethodChangeEventInit& init)
+ : PaymentRequestUpdateEvent(ExecutionContext::From(script_state),
+ type,
+ init),
+ method_name_(init.methodName()),
+ method_details_(init.hasMethodDetails()
+ ? init.methodDetails()
+ : ScriptValue::CreateNull(script_state)) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h
new file mode 100644
index 00000000000..f557cbcd21f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h
@@ -0,0 +1,47 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_METHOD_CHANGE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_METHOD_CHANGE_EVENT_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/payments/payment_method_change_event_init.h"
+#include "third_party/blink/renderer/modules/payments/payment_request_update_event.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ScriptState;
+
+class MODULES_EXPORT PaymentMethodChangeEvent final
+ : public PaymentRequestUpdateEvent {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ ~PaymentMethodChangeEvent() override;
+
+ static PaymentMethodChangeEvent* Create(
+ ScriptState*,
+ const AtomicString& type,
+ const PaymentMethodChangeEventInit& = PaymentMethodChangeEventInit());
+
+ const String& methodName() const;
+ const ScriptValue methodDetails(ScriptState*) const;
+
+ private:
+ PaymentMethodChangeEvent(ScriptState*,
+ const AtomicString& type,
+ const PaymentMethodChangeEventInit&);
+
+ String method_name_;
+ ScriptValue method_details_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_METHOD_CHANGE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl
new file mode 100644
index 00000000000..98e6d845206
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl
@@ -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.
+
+// https://w3c.github.io/payment-request/#paymentmethodchangeevent-interface
+
+[
+ RuntimeEnabled=PaymentMethodChangeEvent,
+ ConstructorCallWith=ScriptState,
+ Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict),
+ SecureContext,
+ Exposed=Window
+] interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent {
+ readonly attribute DOMString methodName;
+ [CallWith=ScriptState] readonly attribute object? methodDetails;
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl
new file mode 100644
index 00000000000..71e71402f30
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl
@@ -0,0 +1,10 @@
+// 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.
+
+// https://w3c.github.io/payment-request/#paymentmethodchangeeventinit-dictionary
+
+dictionary PaymentMethodChangeEventInit : PaymentRequestUpdateEventInit {
+ DOMString methodName = "";
+ object? methodDetails = null;
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
index 18edea360e1..e16c732ce23 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -9,6 +9,7 @@
#include "base/location.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_feature.mojom-blink.h"
@@ -40,7 +41,7 @@
#include "third_party/blink/renderer/modules/payments/basic_card_helper.h"
#include "third_party/blink/renderer/modules/payments/basic_card_request.h"
#include "third_party/blink/renderer/modules/payments/html_iframe_element_payments.h"
-#include "third_party/blink/renderer/modules/payments/payer_error_fields.h"
+#include "third_party/blink/renderer/modules/payments/payer_errors.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
#include "third_party/blink/renderer/modules/payments/payment_details_init.h"
#include "third_party/blink/renderer/modules/payments/payment_details_update.h"
@@ -52,10 +53,10 @@
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/uuid.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -64,8 +65,8 @@ namespace {
using ::payments::mojom::blink::AddressErrors;
using ::payments::mojom::blink::AddressErrorsPtr;
using ::payments::mojom::blink::CanMakePaymentQueryResult;
-using ::payments::mojom::blink::PayerErrorFields;
-using ::payments::mojom::blink::PayerErrorFieldsPtr;
+using ::payments::mojom::blink::PayerErrors;
+using ::payments::mojom::blink::PayerErrorsPtr;
using ::payments::mojom::blink::PaymentAddress;
using ::payments::mojom::blink::PaymentAddressPtr;
using ::payments::mojom::blink::PaymentCurrencyAmount;
@@ -149,9 +150,8 @@ struct TypeConverter<PaymentValidationErrorsPtr,
const blink::PaymentValidationErrors& input) {
PaymentValidationErrorsPtr output =
payments::mojom::blink::PaymentValidationErrors::New();
- output->payer = input.hasPayer()
- ? PayerErrorFields::From(input.payer())
- : PayerErrorFields::From(blink::PayerErrorFields());
+ output->payer = input.hasPayer() ? PayerErrors::From(input.payer())
+ : PayerErrors::From(blink::PayerErrors());
output->shipping_address =
input.hasShippingAddress()
? AddressErrors::From(input.shippingAddress())
@@ -161,10 +161,9 @@ struct TypeConverter<PaymentValidationErrorsPtr,
};
template <>
-struct TypeConverter<PayerErrorFieldsPtr, blink::PayerErrorFields> {
- static PayerErrorFieldsPtr Convert(const blink::PayerErrorFields& input) {
- PayerErrorFieldsPtr output =
- payments::mojom::blink::PayerErrorFields::New();
+struct TypeConverter<PayerErrorsPtr, blink::PayerErrors> {
+ static PayerErrorsPtr Convert(const blink::PayerErrors& input) {
+ PayerErrorsPtr output = payments::mojom::blink::PayerErrors::New();
output->email = input.hasEmail() ? input.email() : g_empty_string;
output->name = input.hasName() ? input.name() : g_empty_string;
output->phone = input.hasPhone() ? input.phone() : g_empty_string;
@@ -541,6 +540,10 @@ void CountPaymentRequestNetworkNameInSupportedMethod(
bool IsValidMethodFormat(const String& identifier) {
KURL url(NullURL(), identifier);
if (url.IsValid()) {
+ // Allow localhost payment method for test.
+ if (SecurityOrigin::Create(url)->IsLocalhost())
+ return true;
+
// URL PMI validation rules:
// https://www.w3.org/TR/payment-method-id/#dfn-validate-a-url-based-payment-method-identifier
return url.Protocol() == "https" && url.User().IsEmpty() &&
@@ -675,7 +678,7 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate& input,
return;
}
- if (input.hasError() && !input.error().IsNull()) {
+ if (input.hasError()) {
String error_message;
if (!PaymentsValidators::IsValidErrorMsgFormat(input.error(),
&error_message)) {
@@ -683,8 +686,18 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate& input,
return;
}
output->error = input.error();
- } else {
- output->error = "";
+ }
+
+ if (input.hasShippingAddressErrors()) {
+ String error_message;
+ if (!PaymentsValidators::IsValidAddressErrorsFormat(
+ input.shippingAddressErrors(), &error_message)) {
+ exception_state.ThrowTypeError(error_message);
+ return;
+ }
+ output->shipping_address_errors =
+ payments::mojom::blink::AddressErrors::From(
+ input.shippingAddressErrors());
}
}
@@ -731,17 +744,19 @@ void ValidateAndConvertPaymentMethodData(
}
}
-bool AllowedToUsePaymentRequest(const Frame* frame) {
+bool AllowedToUsePaymentRequest(const ExecutionContext* execution_context) {
// To determine whether a Document object |document| is allowed to use the
// feature indicated by attribute name |allowpaymentrequest|, run these steps:
+ // Note: PaymentRequest is only exposed to Window and not workers.
// 1. If |document| has no browsing context, then return false.
- if (!frame)
+ const Document* document = To<Document>(execution_context);
+ if (!document->GetFrame())
return false;
// 2. If Feature Policy is enabled, return the policy for "payment" feature.
- return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment,
- ReportOptions::kReportOnFailure);
+ return document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment,
+ ReportOptions::kReportOnFailure);
}
void WarnIgnoringQueryQuotaForCanMakePayment(
@@ -792,7 +807,7 @@ ScriptPromise PaymentRequest::show(ScriptState* script_state) {
// TODO(crbug.com/825270): Reject with SecurityError DOMException if triggered
// without user activation.
- bool is_user_gesture = Frame::HasTransientUserActivation(GetFrame());
+ bool is_user_gesture = LocalFrame::HasTransientUserActivation(GetFrame());
if (!is_user_gesture) {
UseCounter::Count(GetExecutionContext(),
WebFeature::kPaymentRequestShowWithoutGesture);
@@ -1048,7 +1063,7 @@ PaymentRequest::PaymentRequest(ExecutionContext* execution_context,
&PaymentRequest::OnCompleteTimeout) {
DCHECK(GetExecutionContext()->IsSecureContext());
- if (!AllowedToUsePaymentRequest(GetFrame())) {
+ if (!AllowedToUsePaymentRequest(execution_context)) {
exception_state.ThrowSecurityError(
"Must be in a top-level browsing context or an iframe needs to specify "
"'allowpaymentrequest' explicitly");
@@ -1152,6 +1167,20 @@ void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) {
}
}
+void PaymentRequest::OnPayerDetailChange(
+ payments::mojom::blink::PayerDetailPtr detail) {
+ DCHECK(payment_response_);
+ DCHECK(GetPendingAcceptPromiseResolver());
+ DCHECK(!complete_resolver_);
+
+ PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create(
+ GetExecutionContext(), EventTypeNames::payerdetailchange);
+ event->SetTarget(payment_response_);
+ event->SetPaymentDetailsUpdater(this);
+ payment_response_->UpdatePayerDetail(std::move(detail));
+ payment_response_->DispatchEvent(*event);
+}
+
void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
DCHECK(GetPendingAcceptPromiseResolver());
DCHECK(!complete_resolver_);
@@ -1184,12 +1213,13 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
}
}
- if ((options_.requestPayerName() && response->payer_name.IsEmpty()) ||
- (options_.requestPayerEmail() && response->payer_email.IsEmpty()) ||
- (options_.requestPayerPhone() && response->payer_phone.IsEmpty()) ||
- (!options_.requestPayerName() && !response->payer_name.IsNull()) ||
- (!options_.requestPayerEmail() && !response->payer_email.IsNull()) ||
- (!options_.requestPayerPhone() && !response->payer_phone.IsNull())) {
+ DCHECK(response->payer);
+ if ((options_.requestPayerName() && response->payer->name.IsEmpty()) ||
+ (options_.requestPayerEmail() && response->payer->email.IsEmpty()) ||
+ (options_.requestPayerPhone() && response->payer->phone.IsEmpty()) ||
+ (!options_.requestPayerName() && !response->payer->name.IsNull()) ||
+ (!options_.requestPayerEmail() && !response->payer->email.IsNull()) ||
+ (!options_.requestPayerPhone() && !response->payer->phone.IsNull())) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError));
ClearResolversAndCloseMojoConnection();
return;
@@ -1199,7 +1229,8 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
if (retry_resolver_) {
DCHECK(payment_response_);
- payment_response_->Update(std::move(response), shipping_address_.Get());
+ payment_response_->Update(retry_resolver_->GetScriptState(),
+ std::move(response), shipping_address_.Get());
retry_resolver_->Resolve();
// Do not close the mojo connection here. The merchant website should call
@@ -1207,7 +1238,8 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
// connection to display a success or failure message to the user.
retry_resolver_.Clear();
} else if (accept_resolver_) {
- payment_response_ = new PaymentResponse(std::move(response),
+ payment_response_ = new PaymentResponse(accept_resolver_->GetScriptState(),
+ std::move(response),
shipping_address_.Get(), this, id_);
accept_resolver_->Resolve(payment_response_);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.h b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
index 4a722414604..0b264dc9458 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
@@ -71,6 +71,7 @@ class MODULES_EXPORT PaymentRequest final
DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingaddresschange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingoptionchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(paymentmethodchange);
ScriptPromise canMakePayment(ScriptState*);
@@ -116,6 +117,7 @@ class MODULES_EXPORT PaymentRequest final
void OnShippingAddressChange(
payments::mojom::blink::PaymentAddressPtr) override;
void OnShippingOptionChange(const String& shipping_option_id) override;
+ void OnPayerDetailChange(payments::mojom::blink::PayerDetailPtr) override;
void OnPaymentResponse(payments::mojom::blink::PaymentResponsePtr) override;
void OnError(payments::mojom::blink::PaymentErrorReason) override;
void OnComplete() override;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
index 41e01295d93..f7837401510 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
@@ -25,4 +25,5 @@
attribute EventHandler onshippingaddresschange;
attribute EventHandler onshippingoptionchange;
+ [RuntimeEnabled=PaymentMethodChangeEvent] attribute EventHandler onpaymentmethodchange;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
index a411eb90f26..2b422f7b0ed 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/workers/worker_location.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -104,7 +103,7 @@ ScriptPromise PaymentRequestEvent::openWindow(ScriptState* script_state,
context->ConsumeWindowInteraction();
ServiceWorkerGlobalScopeClient::From(context)->OpenWindowForPaymentHandler(
- parsed_url_to_open, std::make_unique<NavigateClientCallback>(resolver));
+ parsed_url_to_open, resolver);
return promise;
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
index 62401d47f3e..27380478aad 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h
@@ -20,8 +20,8 @@ class ExceptionState;
class ExecutionContext;
class ScriptState;
-class MODULES_EXPORT PaymentRequestUpdateEvent final : public Event,
- public PaymentUpdater {
+class MODULES_EXPORT PaymentRequestUpdateEvent : public Event,
+ public PaymentUpdater {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PaymentRequestUpdateEvent)
@@ -47,11 +47,12 @@ class MODULES_EXPORT PaymentRequestUpdateEvent final : public Event,
void OnUpdateEventTimeoutForTesting();
- private:
+ protected:
PaymentRequestUpdateEvent(ExecutionContext*,
const AtomicString& type,
const PaymentRequestUpdateEventInit&);
+ private:
void OnUpdateEventTimeout(TimerBase*);
// True after event.updateWith() was called.
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
index eb6539bba9b..68f5ae9f221 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
@@ -10,47 +10,82 @@
#include "third_party/blink/renderer/modules/payments/payment_state_resolver.h"
#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
PaymentResponse::PaymentResponse(
+ ScriptState* script_state,
payments::mojom::blink::PaymentResponsePtr response,
PaymentAddress* shipping_address,
PaymentStateResolver* payment_state_resolver,
- const String& requestId)
- : requestId_(requestId),
+ const String& request_id)
+ : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ request_id_(request_id),
method_name_(response->method_name),
- stringified_details_(response->stringified_details),
shipping_address_(shipping_address),
shipping_option_(response->shipping_option),
- payer_name_(response->payer_name),
- payer_email_(response->payer_email),
- payer_phone_(response->payer_phone),
+ payer_name_(response->payer->name),
+ payer_email_(response->payer->email),
+ payer_phone_(response->payer->phone),
payment_state_resolver_(payment_state_resolver) {
DCHECK(payment_state_resolver_);
+ UpdateDetailsFromJSON(script_state, response->stringified_details);
}
PaymentResponse::~PaymentResponse() = default;
void PaymentResponse::Update(
+ ScriptState* script_state,
payments::mojom::blink::PaymentResponsePtr response,
PaymentAddress* shipping_address) {
DCHECK(response);
+ DCHECK(response->payer);
method_name_ = response->method_name;
- stringified_details_ = response->stringified_details;
shipping_address_ = shipping_address;
shipping_option_ = response->shipping_option;
- payer_name_ = response->payer_name;
- payer_email_ = response->payer_email;
- payer_phone_ = response->payer_phone;
+ payer_name_ = response->payer->name;
+ payer_email_ = response->payer->email;
+ payer_phone_ = response->payer->phone;
+ UpdateDetailsFromJSON(script_state, response->stringified_details);
+}
+
+void PaymentResponse::UpdatePayerDetail(
+ payments::mojom::blink::PayerDetailPtr detail) {
+ DCHECK(detail);
+ payer_name_ = detail->name;
+ payer_email_ = detail->email;
+ payer_phone_ = detail->phone;
+}
+
+void PaymentResponse::UpdateDetailsFromJSON(ScriptState* script_state,
+ const String& json) {
+ ScriptState::Scope scope(script_state);
+ if (json.IsEmpty()) {
+ details_ = V8ObjectBuilder(script_state).GetScriptValue();
+ return;
+ }
+
+ ExceptionState exception_state(script_state->GetIsolate(),
+ ExceptionState::kConstructionContext,
+ "PaymentResponse");
+ v8::Local<v8::Value> parsed_value =
+ FromJSONString(script_state->GetIsolate(), script_state->GetContext(),
+ json, exception_state);
+ if (exception_state.HadException()) {
+ exception_state.ClearException();
+ details_ = V8ObjectBuilder(script_state).GetScriptValue();
+ return;
+ }
+ details_ = ScriptValue(script_state, parsed_value);
}
ScriptValue PaymentResponse::toJSONForBinding(ScriptState* script_state) const {
V8ObjectBuilder result(script_state);
result.AddString("requestId", requestId());
result.AddString("methodName", methodName());
- result.Add("details", details(script_state, ASSERT_NO_EXCEPTION));
+ result.Add("details", details(script_state));
if (shippingAddress())
result.Add("shippingAddress",
@@ -66,12 +101,8 @@ ScriptValue PaymentResponse::toJSONForBinding(ScriptState* script_state) const {
return result.GetScriptValue();
}
-ScriptValue PaymentResponse::details(ScriptState* script_state,
- ExceptionState& exception_state) const {
- return ScriptValue(
- script_state,
- FromJSONString(script_state->GetIsolate(), script_state->GetContext(),
- stringified_details_, exception_state));
+ScriptValue PaymentResponse::details(ScriptState* script_state) const {
+ return ScriptValue(script_state, details_.V8ValueFor(script_state));
}
ScriptPromise PaymentResponse::complete(ScriptState* script_state,
@@ -91,10 +122,23 @@ ScriptPromise PaymentResponse::retry(
return payment_state_resolver_->Retry(script_state, error_fields);
}
+bool PaymentResponse::HasPendingActivity() const {
+ return !!payment_state_resolver_;
+}
+
+const AtomicString& PaymentResponse::InterfaceName() const {
+ return EventTypeNames::payerdetailchange;
+}
+
+ExecutionContext* PaymentResponse::GetExecutionContext() const {
+ return ContextLifecycleObserver::GetExecutionContext();
+}
+
void PaymentResponse::Trace(blink::Visitor* visitor) {
visitor->Trace(shipping_address_);
visitor->Trace(payment_state_resolver_);
- ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
+ ContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.h b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
index 7bbef17b997..f20071dc9f7 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
@@ -6,8 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_RESPONSE_H_
#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/payments/payment_currency_amount.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -17,30 +20,38 @@
namespace blink {
-class ExceptionState;
class PaymentAddress;
class PaymentStateResolver;
class PaymentValidationErrors;
class ScriptState;
-class MODULES_EXPORT PaymentResponse final : public ScriptWrappable {
+class MODULES_EXPORT PaymentResponse final
+ : public EventTargetWithInlineData,
+ public ContextLifecycleObserver,
+ public ActiveScriptWrappable<PaymentResponse> {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(PaymentResponse);
WTF_MAKE_NONCOPYABLE(PaymentResponse);
public:
- PaymentResponse(payments::mojom::blink::PaymentResponsePtr,
- PaymentAddress* shipping_address_,
- PaymentStateResolver*,
- const String& requestId);
+ PaymentResponse(ScriptState* script_state,
+ payments::mojom::blink::PaymentResponsePtr response,
+ PaymentAddress* shipping_address,
+ PaymentStateResolver* payment_state_resolver,
+ const String& request_id);
~PaymentResponse() override;
- void Update(payments::mojom::blink::PaymentResponsePtr, PaymentAddress*);
+ void Update(ScriptState* script_state,
+ payments::mojom::blink::PaymentResponsePtr response,
+ PaymentAddress* shipping_address);
+ void UpdatePayerDetail(payments::mojom::blink::PayerDetailPtr);
+ void UpdateDetailsFromJSON(ScriptState* script_state, const String& json);
ScriptValue toJSONForBinding(ScriptState*) const;
- const String& requestId() const { return requestId_; }
+ const String& requestId() const { return request_id_; }
const String& methodName() const { return method_name_; }
- ScriptValue details(ScriptState*, ExceptionState&) const;
+ ScriptValue details(ScriptState* script_state) const;
PaymentAddress* shippingAddress() const { return shipping_address_.Get(); }
const String& shippingOption() const { return shipping_option_; }
const String& payerName() const { return payer_name_; }
@@ -50,12 +61,19 @@ class MODULES_EXPORT PaymentResponse final : public ScriptWrappable {
ScriptPromise complete(ScriptState*, const String& result = "");
ScriptPromise retry(ScriptState*, const PaymentValidationErrors&);
+ bool HasPendingActivity() const override;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(payerdetailchange);
+
+ const AtomicString& InterfaceName() const override;
+ ExecutionContext* GetExecutionContext() const override;
+
void Trace(blink::Visitor*) override;
private:
- String requestId_;
+ String request_id_;
String method_name_;
- String stringified_details_;
+ ScriptValue details_;
Member<PaymentAddress> shipping_address_;
String shipping_option_;
String payer_name_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.idl b/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
index 545ede68953..31096ecec5d 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
@@ -15,13 +15,14 @@ enum PaymentComplete {
[
RuntimeEnabled=PaymentRequest,
SecureContext,
- Exposed=Window
-] interface PaymentResponse {
+ Exposed=Window,
+ ActiveScriptWrappable
+] interface PaymentResponse : EventTarget {
serializer = {attribute};
readonly attribute DOMString requestId;
readonly attribute DOMString methodName;
- [CallWith=ScriptState, RaisesException] readonly attribute object details;
+ [CallWith=ScriptState] readonly attribute object details;
readonly attribute PaymentAddress? shippingAddress;
readonly attribute DOMString? shippingOption;
readonly attribute DOMString? payerName;
@@ -30,4 +31,6 @@ enum PaymentComplete {
[CallWith=ScriptState, NewObject] Promise<void> complete(optional PaymentComplete paymentResult = "unknown");
[CallWith=ScriptState, NewObject, RuntimeEnabled=PaymentRetry] Promise<void> retry(PaymentValidationErrors errorFields);
+
+ [RuntimeEnabled=PaymentRetry] attribute EventHandler onpayerdetailchange;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
index 53c12f8a740..5f1b4d99506 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
#include "third_party/blink/renderer/modules/payments/payment_state_resolver.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
@@ -53,13 +54,14 @@ TEST(PaymentResponseTest, DataCopiedOver) {
input->method_name = "foo";
input->stringified_details = "{\"transactionId\": 123}";
input->shipping_option = "standardShippingOption";
- input->payer_name = "Jon Doe";
- input->payer_email = "abc@gmail.com";
- input->payer_phone = "0123";
+ input->payer->name = "Jon Doe";
+ input->payer->email = "abc@gmail.com";
+ input->payer->phone = "0123";
MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
PaymentResponse* output =
- new PaymentResponse(std::move(input), nullptr, complete_callback, "id");
+ new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
+ complete_callback, "id");
EXPECT_EQ("foo", output->methodName());
EXPECT_EQ("standardShippingOption", output->shippingOption());
@@ -68,8 +70,7 @@ TEST(PaymentResponseTest, DataCopiedOver) {
EXPECT_EQ("0123", output->payerPhone());
EXPECT_EQ("id", output->requestId());
- ScriptValue details =
- output->details(scope.GetScriptState(), scope.GetExceptionState());
+ ScriptValue details = output->details(scope.GetScriptState());
ASSERT_FALSE(scope.GetExceptionState().HadException());
ASSERT_TRUE(details.V8Value()->IsObject());
@@ -83,19 +84,41 @@ TEST(PaymentResponseTest, DataCopiedOver) {
EXPECT_EQ(123, transaction_id.V8Value().As<v8::Number>()->Value());
}
-TEST(PaymentResponseTest, PaymentResponseDetailsJSONObject) {
+TEST(PaymentResponseTest,
+ PaymentResponseDetailsWithUnexpectedJSONFormatString) {
V8TestingScope scope;
payments::mojom::blink::PaymentResponsePtr input =
BuildPaymentResponseForTest();
input->stringified_details = "transactionId";
MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
PaymentResponse* output =
- new PaymentResponse(std::move(input), nullptr, complete_callback, "id");
+ new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
+ complete_callback, "id");
- ScriptValue details =
- output->details(scope.GetScriptState(), scope.GetExceptionState());
+ ScriptValue details = output->details(scope.GetScriptState());
+ ASSERT_TRUE(details.V8Value()->IsObject());
+
+ String stringified_details = ToBlinkString<String>(
+ v8::JSON::Stringify(scope.GetContext(),
+ details.V8Value().As<v8::Object>())
+ .ToLocalChecked(),
+ kDoNotExternalize);
+
+ EXPECT_EQ("{}", stringified_details);
+}
- ASSERT_TRUE(scope.GetExceptionState().HadException());
+TEST(PaymentResponseTest, PaymentResponseDetailsRetrunsTheSameObject) {
+ V8TestingScope scope;
+ payments::mojom::blink::PaymentResponsePtr input =
+ BuildPaymentResponseForTest();
+ input->method_name = "foo";
+ input->stringified_details = "{\"transactionId\": 123}";
+ MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
+ PaymentResponse* output =
+ new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
+ complete_callback, "id");
+ EXPECT_EQ(output->details(scope.GetScriptState()),
+ output->details(scope.GetScriptState()));
}
TEST(PaymentResponseTest, CompleteCalledWithSuccess) {
@@ -106,7 +129,8 @@ TEST(PaymentResponseTest, CompleteCalledWithSuccess) {
input->stringified_details = "{\"transactionId\": 123}";
MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
PaymentResponse* output =
- new PaymentResponse(std::move(input), nullptr, complete_callback, "id");
+ new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
+ complete_callback, "id");
EXPECT_CALL(*complete_callback,
Complete(scope.GetScriptState(), PaymentStateResolver::kSuccess));
@@ -122,7 +146,8 @@ TEST(PaymentResponseTest, CompleteCalledWithFailure) {
input->stringified_details = "{\"transactionId\": 123}";
MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
PaymentResponse* output =
- new PaymentResponse(std::move(input), nullptr, complete_callback, "id");
+ new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
+ complete_callback, "id");
EXPECT_CALL(*complete_callback,
Complete(scope.GetScriptState(), PaymentStateResolver::kFail));
@@ -133,13 +158,13 @@ TEST(PaymentResponseTest, CompleteCalledWithFailure) {
TEST(PaymentResponseTest, JSONSerializerTest) {
V8TestingScope scope;
payments::mojom::blink::PaymentResponsePtr input =
- payments::mojom::blink::PaymentResponse::New();
+ BuildPaymentResponseForTest();
input->method_name = "foo";
input->stringified_details = "{\"transactionId\": 123}";
input->shipping_option = "standardShippingOption";
- input->payer_email = "abc@gmail.com";
- input->payer_phone = "0123";
- input->payer_name = "Jon Doe";
+ input->payer->email = "abc@gmail.com";
+ input->payer->phone = "0123";
+ input->payer->name = "Jon Doe";
input->shipping_address = payments::mojom::blink::PaymentAddress::New();
input->shipping_address->country = "US";
input->shipping_address->language_code = "en";
@@ -150,8 +175,9 @@ TEST(PaymentResponseTest, JSONSerializerTest) {
PaymentAddress* address =
new PaymentAddress(std::move(input->shipping_address));
- PaymentResponse* output = new PaymentResponse(
- std::move(input), address, new MockPaymentStateResolver, "id");
+ PaymentResponse* output =
+ new PaymentResponse(scope.GetScriptState(), std::move(input), address,
+ new MockPaymentStateResolver, "id");
ScriptValue json_object = output->toJSONForBinding(scope.GetScriptState());
EXPECT_TRUE(json_object.IsObject());
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
index 01b16898ce4..b532619a039 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
@@ -191,6 +191,7 @@ HeapVector<PaymentMethodData> BuildPaymentMethodDataForTest() {
payments::mojom::blink::PaymentResponsePtr BuildPaymentResponseForTest() {
payments::mojom::blink::PaymentResponsePtr result =
payments::mojom::blink::PaymentResponse::New();
+ result->payer = payments::mojom::blink::PayerDetail::New();
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_validation_errors.idl b/chromium/third_party/blink/renderer/modules/payments/payment_validation_errors.idl
index d25f288226b..518ea1d2dae 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_validation_errors.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_validation_errors.idl
@@ -5,6 +5,6 @@
// https://w3c.github.io/payment-request/#dom-paymentvalidationerrors
dictionary PaymentValidationErrors {
- PayerErrorFields payer;
+ PayerErrors payer;
AddressErrors shippingAddress;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc b/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
index 3b2bdeccca4..467d970f0c1 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
+#include "third_party/blink/renderer/modules/payments/address_errors.h"
+#include "third_party/blink/renderer/modules/payments/payer_errors.h"
#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
@@ -126,65 +128,60 @@ bool PaymentsValidators::IsValidErrorMsgFormat(const String& error,
}
// static
-bool PaymentsValidators::IsValidPaymentValidationErrorsFormat(
- const PaymentValidationErrors& errors,
+bool PaymentsValidators::IsValidAddressErrorsFormat(
+ const AddressErrors& errors,
String* optional_error_message) {
- if (errors.hasPayer()) {
- if ((errors.payer().hasEmail() &&
- !IsValidErrorMsgFormat(errors.payer().email(),
- optional_error_message)) ||
- (errors.payer().hasName() &&
- !IsValidErrorMsgFormat(errors.payer().name(),
- optional_error_message)) ||
- (errors.payer().hasPhone() &&
- !IsValidErrorMsgFormat(errors.payer().phone(),
- optional_error_message))) {
- return false;
- }
- }
+ return (!errors.hasAddressLine() ||
+ IsValidErrorMsgFormat(errors.addressLine(),
+ optional_error_message)) &&
+ (!errors.hasCity() ||
+ IsValidErrorMsgFormat(errors.city(), optional_error_message)) &&
+ (!errors.hasCountry() ||
+ IsValidErrorMsgFormat(errors.country(), optional_error_message)) &&
+ (!errors.hasDependentLocality() ||
+ IsValidErrorMsgFormat(errors.dependentLocality(),
+ optional_error_message)) &&
+ (!errors.hasLanguageCode() ||
+ IsValidErrorMsgFormat(errors.languageCode(),
+ optional_error_message)) &&
+ (!errors.hasOrganization() ||
+ IsValidErrorMsgFormat(errors.organization(),
+ optional_error_message)) &&
+ (!errors.hasPhone() ||
+ IsValidErrorMsgFormat(errors.phone(), optional_error_message)) &&
+ (!errors.hasPostalCode() ||
+ IsValidErrorMsgFormat(errors.postalCode(), optional_error_message)) &&
+ (!errors.hasRecipient() ||
+ IsValidErrorMsgFormat(errors.recipient(), optional_error_message)) &&
+ (!errors.hasRegion() ||
+ IsValidErrorMsgFormat(errors.region(), optional_error_message)) &&
+ (!errors.hasRegionCode() ||
+ IsValidErrorMsgFormat(errors.regionCode(), optional_error_message)) &&
+ (!errors.hasSortingCode() ||
+ IsValidErrorMsgFormat(errors.sortingCode(), optional_error_message));
+}
- if (errors.hasShippingAddress()) {
- if ((errors.shippingAddress().hasAddressLine() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().addressLine(),
- optional_error_message)) ||
- (errors.shippingAddress().hasCity() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().city(),
- optional_error_message)) ||
- (errors.shippingAddress().hasCountry() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().country(),
- optional_error_message)) ||
- (errors.shippingAddress().hasDependentLocality() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().dependentLocality(),
- optional_error_message)) ||
- (errors.shippingAddress().hasLanguageCode() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().languageCode(),
- optional_error_message)) ||
- (errors.shippingAddress().hasOrganization() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().organization(),
- optional_error_message)) ||
- (errors.shippingAddress().hasPhone() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().phone(),
- optional_error_message)) ||
- (errors.shippingAddress().hasPostalCode() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().postalCode(),
- optional_error_message)) ||
- (errors.shippingAddress().hasRecipient() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().recipient(),
- optional_error_message)) ||
- (errors.shippingAddress().hasRegion() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().region(),
- optional_error_message)) ||
- (errors.shippingAddress().hasRegionCode() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().regionCode(),
- optional_error_message)) ||
- (errors.shippingAddress().hasSortingCode() &&
- !IsValidErrorMsgFormat(errors.shippingAddress().sortingCode(),
- optional_error_message))) {
- return false;
- }
- }
+// static
+bool PaymentsValidators::IsValidPayerErrorsFormat(
+ const PayerErrors& errors,
+ String* optional_error_message) {
+ return (!errors.hasEmail() ||
+ IsValidErrorMsgFormat(errors.email(), optional_error_message)) &&
+ (!errors.hasName() ||
+ IsValidErrorMsgFormat(errors.name(), optional_error_message)) &&
+ (!errors.hasPhone() ||
+ IsValidErrorMsgFormat(errors.phone(), optional_error_message));
+}
- return true;
+// static
+bool PaymentsValidators::IsValidPaymentValidationErrorsFormat(
+ const PaymentValidationErrors& errors,
+ String* optional_error_message) {
+ return (!errors.hasPayer() ||
+ IsValidPayerErrorsFormat(errors.payer(), optional_error_message)) &&
+ (!errors.hasShippingAddress() ||
+ IsValidAddressErrorsFormat(errors.shippingAddress(),
+ optional_error_message));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators.h b/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
index c9c2f86f38e..1a7d384165b 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
@@ -12,6 +12,8 @@
namespace blink {
+class AddressErrors;
+class PayerErrors;
class PaymentValidationErrors;
class MODULES_EXPORT PaymentsValidators final {
@@ -54,8 +56,15 @@ class MODULES_EXPORT PaymentsValidators final {
static bool IsValidErrorMsgFormat(const String& code,
String* optional_error_message);
- // Returns false if |payment_validation_errors| has too long string (greater
- // than 2048).
+ // Returns false if |errors| has too long string (greater than 2048).
+ static bool IsValidAddressErrorsFormat(const AddressErrors& errors,
+ String* optional_error_message);
+
+ // Returns false if |errors| has too long string (greater than 2048).
+ static bool IsValidPayerErrorsFormat(const PayerErrors& errors,
+ String* optional_error_message);
+
+ // Returns false if |errors| has too long string (greater than 2048).
static bool IsValidPaymentValidationErrorsFormat(
const PaymentValidationErrors& errors,
String* optional_error_message);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
index 3f2928c34da..431c7751226 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc
@@ -296,7 +296,7 @@ PaymentValidationErrors toPaymentValidationErrors(
ValidationErrorsTestCase test_case) {
PaymentValidationErrors errors;
- PayerErrorFields payer;
+ PayerErrors payer;
payer.setEmail(test_case.m_payer_email);
payer.setName(test_case.m_payer_name);
payer.setPhone(test_case.m_payer_phone);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
index 70eb3421216..0592dce010e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -6,10 +6,32 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("peerconnection") {
sources = [
+ "adapters/ice_transport_adapter.h",
+ "adapters/ice_transport_adapter_cross_thread_factory.h",
+ "adapters/ice_transport_adapter_impl.cc",
+ "adapters/ice_transport_adapter_impl.h",
"adapters/ice_transport_host.cc",
"adapters/ice_transport_host.h",
"adapters/ice_transport_proxy.cc",
"adapters/ice_transport_proxy.h",
+ "adapters/p2p_quic_packet_transport.h",
+ "adapters/p2p_quic_stream.h",
+ "adapters/p2p_quic_stream_impl.cc",
+ "adapters/p2p_quic_stream_impl.h",
+ "adapters/p2p_quic_transport.h",
+ "adapters/p2p_quic_transport_factory.h",
+ "adapters/p2p_quic_transport_factory_impl.cc",
+ "adapters/p2p_quic_transport_factory_impl.h",
+ "adapters/p2p_quic_transport_impl.cc",
+ "adapters/p2p_quic_transport_impl.h",
+ "adapters/quic_stream_host.cc",
+ "adapters/quic_stream_host.h",
+ "adapters/quic_stream_proxy.cc",
+ "adapters/quic_stream_proxy.h",
+ "adapters/quic_transport_host.cc",
+ "adapters/quic_transport_host.h",
+ "adapters/quic_transport_proxy.cc",
+ "adapters/quic_transport_proxy.h",
"adapters/web_rtc_cross_thread_copier.cc",
"adapters/web_rtc_cross_thread_copier.h",
"rtc_certificate.cc",
@@ -36,6 +58,8 @@ blink_modules_sources("peerconnection") {
"rtc_peer_connection_ice_event.h",
"rtc_quic_stream.cc",
"rtc_quic_stream.h",
+ "rtc_quic_stream_event.cc",
+ "rtc_quic_stream_event.h",
"rtc_quic_transport.cc",
"rtc_quic_transport.h",
"rtc_rtp_contributing_source.cc",
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
index 1e08706b174..8fe2aa371f2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
@@ -7,4 +7,8 @@ include_rules = [
"+third_party/blink/renderer/modules/mediastream",
"+third_party/blink/renderer/modules/modules_export.h",
"+third_party/blink/renderer/modules/peerconnection",
+ "+net/third_party/quic",
+ "+net/quic/chromium",
+ "+net/quic",
+ "+net/test",
]
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h
new file mode 100644
index 00000000000..77354113979
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h
@@ -0,0 +1,89 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_H_
+
+#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
+
+namespace blink {
+
+class P2PQuicPacketTransport;
+
+// Defines the ICE candidate policy the browser uses to surface the permitted
+// candidates to the application.
+// https://w3c.github.io/webrtc-pc/#dom-rtcicetransportpolicy
+enum class IceTransportPolicy {
+ // The ICE Agent uses only media relay candidates.
+ kRelay,
+ // The ICE Agent can use any type of candidate.
+ kAll
+};
+
+// The IceTransportAdapter is the API used by the RTCIceTransport Blink binding
+// to interact with the ICE implementation. It exactly mirrors the requirements
+// of the RTCIceTransport: each JavaScript method that must interact with the
+// ICE implementation should map to exactly one method call on this interface.
+// This interface is designed to be fully asynchronous; all methods are void and
+// callbacks occur via the Delegate (implemented by the client).
+//
+// The ICE Agent is immediately active once this object has been constructed. It
+// can be stopped by deleting the IceTransportAdapter.
+class IceTransportAdapter {
+ public:
+ // Delegate to receive callbacks from the IceTransportAdapter. The Delegate
+ // must outlive the IceTransportAdapter.
+ class Delegate {
+ public:
+ virtual ~Delegate() = default;
+
+ // Called asynchronously when the ICE gathering state changes.
+ virtual void OnGatheringStateChanged(cricket::IceGatheringState new_state) {
+ }
+
+ // Called asynchronously when a new ICE candidate has been gathered.
+ virtual void OnCandidateGathered(const cricket::Candidate& candidate) {}
+
+ // Called asynchronously when the ICE connection state has changed.
+ virtual void OnStateChanged(cricket::IceTransportState new_state) {}
+
+ // Called asynchronously when the ICE agent selects a different candidate
+ // pair for the active connection.
+ virtual void OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) {}
+ };
+
+ virtual ~IceTransportAdapter() = default;
+
+ // Start ICE candidate gathering.
+ virtual void StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ IceTransportPolicy policy) = 0;
+
+ // Start ICE connectivity checks with the given initial remote candidates.
+ virtual void Start(
+ const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates) = 0;
+
+ // Handle a remote ICE restart. This changes the remote parameters and clears
+ // all remote candidates.
+ virtual void HandleRemoteRestart(
+ const cricket::IceParameters& new_remote_parameters) = 0;
+
+ // Adds a remote candidate to potentially start connectivity checks with.
+ // The caller must ensure Start() has already bene called.
+ virtual void AddRemoteCandidate(const cricket::Candidate& candidate) = 0;
+
+ // Gets a P2PQuicPacketTransport that is backed by this ICE connection. The
+ // returned instance lives the same lifetime as the IceTransportAdapter.
+ virtual P2PQuicPacketTransport* packet_transport() const = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h
new file mode 100644
index 00000000000..8d5f51e72cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_CROSS_THREAD_FACTORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_CROSS_THREAD_FACTORY_H_
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h"
+
+namespace blink {
+
+// This class creates a single concrete instance of an IceTransportAdapter with
+// a hook to allow creating dependencies on the main thread (the
+// IceTransportAdapter is created on the worker thread).
+//
+// Callers must call InitializeOnMainThread() before ConstructOnWorkerThread().
+class IceTransportAdapterCrossThreadFactory {
+ public:
+ virtual ~IceTransportAdapterCrossThreadFactory() = default;
+
+ // Construct any dependencies on the main thread. Can only be called once.
+ virtual void InitializeOnMainThread() = 0;
+
+ // Construct the IceTransportAdapter instance with the given delegate. Can
+ // only be called once.
+ virtual std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread(
+ IceTransportAdapter::Delegate* delegate) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_CROSS_THREAD_FACTORY_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
new file mode 100644
index 00000000000..9b0eb52ca30
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -0,0 +1,218 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
+
+namespace blink {
+namespace {
+
+// Implementation of P2PQuicPacketTransport backed by a P2PTransportChannel.
+class QuicPacketTransportAdapter : public P2PQuicPacketTransport,
+ public sigslot::has_slots<> {
+ public:
+ QuicPacketTransportAdapter(
+ cricket::P2PTransportChannel* p2p_transport_channel)
+ : p2p_transport_channel_(p2p_transport_channel) {
+ DCHECK(p2p_transport_channel_);
+ p2p_transport_channel_->SignalReadPacket.connect(
+ this, &QuicPacketTransportAdapter::OnReadPacket);
+ p2p_transport_channel_->SignalWritableState.connect(
+ this, &QuicPacketTransportAdapter::OnWritableState);
+ }
+
+ ~QuicPacketTransportAdapter() override {
+ // Caller is responsible for unsetting the write observer and receive
+ // delegate before destroying this.
+ DCHECK(!write_observer_);
+ DCHECK(!receive_delegate_);
+ }
+
+ int WritePacket(const QuicPacket& packet) override {
+ rtc::PacketOptions options;
+ options.packet_id = packet.packet_number;
+ int flags = 0;
+ return p2p_transport_channel_->SendPacket(packet.buffer, packet.buf_len,
+ options, flags);
+ }
+
+ void SetReceiveDelegate(ReceiveDelegate* receive_delegate) override {
+ receive_delegate_ = receive_delegate;
+ }
+
+ void SetWriteObserver(WriteObserver* write_observer) override {
+ write_observer_ = write_observer;
+ }
+
+ bool Writable() override { return p2p_transport_channel_->writable(); }
+
+ private:
+ // P2PTransportChannel callbacks.
+ void OnReadPacket(rtc::PacketTransportInternal* packet_transport,
+ const char* buffer,
+ size_t buffer_length,
+ const rtc::PacketTime& packet_time,
+ int flags) {
+ DCHECK_EQ(packet_transport, p2p_transport_channel_);
+ if (!receive_delegate_) {
+ // TODO(crbug.com/874296): Consider providing a small buffer.
+ return;
+ }
+ receive_delegate_->OnPacketDataReceived(buffer, buffer_length);
+ }
+ void OnWritableState(rtc::PacketTransportInternal* packet_transport) {
+ DCHECK_EQ(packet_transport, p2p_transport_channel_);
+ if (!write_observer_) {
+ return;
+ }
+ if (p2p_transport_channel_->writable()) {
+ write_observer_->OnCanWrite();
+ }
+ }
+
+ cricket::P2PTransportChannel* p2p_transport_channel_;
+ ReceiveDelegate* receive_delegate_ = nullptr;
+ WriteObserver* write_observer_ = nullptr;
+};
+
+} // namespace
+
+IceTransportAdapterImpl::IceTransportAdapterImpl(
+ Delegate* delegate,
+ std::unique_ptr<cricket::PortAllocator> port_allocator,
+ rtc::Thread* thread)
+ : delegate_(delegate), port_allocator_(std::move(port_allocator)) {
+ // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component.
+ if (!rtc::ThreadManager::Instance()->CurrentThread()) {
+ rtc::ThreadManager::Instance()->SetCurrentThread(thread);
+ }
+
+ // These settings are copied from PeerConnection:
+ // https://codesearch.chromium.org/chromium/src/third_party/webrtc/pc/peerconnection.cc?l=4708&rcl=820ebd0f661696043959b5105b2814e0edd8b694
+ port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ port_allocator_->set_flags(port_allocator_->flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_ENABLE_IPV6 |
+ cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
+ port_allocator_->Initialize();
+
+ p2p_transport_channel_ = std::make_unique<cricket::P2PTransportChannel>(
+ "", 0, port_allocator_.get());
+ p2p_transport_channel_->SignalGatheringState.connect(
+ this, &IceTransportAdapterImpl::OnGatheringStateChanged);
+ p2p_transport_channel_->SignalCandidateGathered.connect(
+ this, &IceTransportAdapterImpl::OnCandidateGathered);
+ p2p_transport_channel_->SignalStateChanged.connect(
+ this, &IceTransportAdapterImpl::OnStateChanged);
+ p2p_transport_channel_->SignalNetworkRouteChanged.connect(
+ this, &IceTransportAdapterImpl::OnNetworkRouteChanged);
+ // We need to set the ICE role even before Start is called since the Port
+ // assumes that the role has been set before receiving incoming connectivity
+ // checks. These checks can race with the information signaled for Start.
+ p2p_transport_channel_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ // The ICE tiebreaker is used to determine which side is controlling/
+ // controlled when both sides start in the same role. The number is randomly
+ // generated so that each peer can calculate a.tiebreaker <= b.tiebreaker
+ // consistently.
+ p2p_transport_channel_->SetIceTiebreaker(rtc::CreateRandomId64());
+ quic_packet_transport_adapter_ = std::make_unique<QuicPacketTransportAdapter>(
+ p2p_transport_channel_.get());
+}
+
+IceTransportAdapterImpl::~IceTransportAdapterImpl() = default;
+
+static uint32_t GetCandidateFilterForPolicy(IceTransportPolicy policy) {
+ switch (policy) {
+ case IceTransportPolicy::kRelay:
+ return cricket::CF_RELAY;
+ case IceTransportPolicy::kAll:
+ return cricket::CF_ALL;
+ }
+ NOTREACHED();
+ return 0;
+}
+
+void IceTransportAdapterImpl::StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ IceTransportPolicy policy) {
+ port_allocator_->set_candidate_filter(GetCandidateFilterForPolicy(policy));
+ port_allocator_->SetConfiguration(stun_servers, turn_servers,
+ port_allocator_->candidate_pool_size(),
+ port_allocator_->prune_turn_ports());
+
+ p2p_transport_channel_->SetIceParameters(local_parameters);
+ p2p_transport_channel_->MaybeStartGathering();
+ DCHECK_EQ(p2p_transport_channel_->gathering_state(),
+ cricket::kIceGatheringGathering);
+}
+
+void IceTransportAdapterImpl::Start(
+ const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates) {
+ p2p_transport_channel_->SetRemoteIceParameters(remote_parameters);
+ p2p_transport_channel_->SetIceRole(role);
+ for (const auto& candidate : initial_remote_candidates) {
+ p2p_transport_channel_->AddRemoteCandidate(candidate);
+ }
+}
+
+void IceTransportAdapterImpl::HandleRemoteRestart(
+ const cricket::IceParameters& new_remote_parameters) {
+ auto remote_candidates = p2p_transport_channel_->remote_candidates();
+ for (const auto& remote_candidate : remote_candidates) {
+ p2p_transport_channel_->RemoveRemoteCandidate(remote_candidate);
+ }
+ p2p_transport_channel_->SetRemoteIceParameters(new_remote_parameters);
+}
+
+void IceTransportAdapterImpl::AddRemoteCandidate(
+ const cricket::Candidate& candidate) {
+ p2p_transport_channel_->AddRemoteCandidate(candidate);
+}
+
+P2PQuicPacketTransport* IceTransportAdapterImpl::packet_transport() const {
+ return quic_packet_transport_adapter_.get();
+}
+
+void IceTransportAdapterImpl::OnGatheringStateChanged(
+ cricket::IceTransportInternal* transport) {
+ DCHECK_EQ(transport, p2p_transport_channel_.get());
+ delegate_->OnGatheringStateChanged(p2p_transport_channel_->gathering_state());
+}
+
+void IceTransportAdapterImpl::OnCandidateGathered(
+ cricket::IceTransportInternal* transport,
+ const cricket::Candidate& candidate) {
+ DCHECK_EQ(transport, p2p_transport_channel_.get());
+ delegate_->OnCandidateGathered(candidate);
+}
+
+void IceTransportAdapterImpl::OnStateChanged(
+ cricket::IceTransportInternal* transport) {
+ DCHECK_EQ(transport, p2p_transport_channel_.get());
+ delegate_->OnStateChanged(p2p_transport_channel_->GetState());
+}
+
+void IceTransportAdapterImpl::OnNetworkRouteChanged(
+ absl::optional<rtc::NetworkRoute> new_network_route) {
+ const cricket::CandidatePairInterface* selected_connection =
+ p2p_transport_channel_->selected_connection();
+ if (!selected_connection) {
+ // The selected connection will only be null if the ICE connection has
+ // totally failed, at which point we'll get a StateChanged signal. The
+ // client will implicitly clear the selected candidate pair when it receives
+ // the failed state change, so we don't need to give an explicit callback
+ // here.
+ return;
+ }
+ delegate_->OnSelectedCandidatePairChanged(
+ std::make_pair(selected_connection->local_candidate(),
+ selected_connection->remote_candidate()));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
new file mode 100644
index 00000000000..0b92df88e9a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h"
+
+namespace blink {
+
+// IceTransportAdapter implementation backed by the WebRTC PortAllocator /
+// P2PTransportChannel.
+class IceTransportAdapterImpl final : public IceTransportAdapter,
+ public sigslot::has_slots<> {
+ public:
+ // Must be constructed on the WebRTC worker thread.
+ // |delegate| must outlive the IceTransportAdapter.
+ // |thread| should be the rtc::Thread instance associated with the WebRTC
+ // worker thread.
+ IceTransportAdapterImpl(
+ Delegate* delegate,
+ std::unique_ptr<cricket::PortAllocator> port_allocator,
+ rtc::Thread* thread);
+ ~IceTransportAdapterImpl() override;
+
+ // IceTransportAdapter overrides.
+ void StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ IceTransportPolicy policy) override;
+ void Start(const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates)
+ override;
+ void HandleRemoteRestart(
+ const cricket::IceParameters& new_remote_parameters) override;
+ void AddRemoteCandidate(const cricket::Candidate& candidate) override;
+ P2PQuicPacketTransport* packet_transport() const override;
+
+ private:
+ // Callbacks from P2PTransportChannel.
+ void OnGatheringStateChanged(cricket::IceTransportInternal* transport);
+ void OnCandidateGathered(cricket::IceTransportInternal* transport,
+ const cricket::Candidate& candidate);
+ void OnStateChanged(cricket::IceTransportInternal* transport);
+ void OnNetworkRouteChanged(
+ absl::optional<rtc::NetworkRoute> new_network_route);
+
+ Delegate* const delegate_;
+ std::unique_ptr<cricket::PortAllocator> port_allocator_;
+ std::unique_ptr<cricket::P2PTransportChannel> p2p_transport_channel_;
+ std::unique_ptr<P2PQuicPacketTransport> quic_packet_transport_adapter_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_ADAPTER_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc
index 34ce669362c..5860ed120ed 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
@@ -13,117 +14,124 @@ namespace blink {
IceTransportHost::IceTransportHost(
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
- base::WeakPtr<IceTransportProxy> proxy,
- std::unique_ptr<cricket::PortAllocator> port_allocator)
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ base::WeakPtr<IceTransportProxy> proxy)
: proxy_thread_(std::move(proxy_thread)),
- port_allocator_(std::move(port_allocator)),
+ host_thread_(std::move(host_thread)),
proxy_(std::move(proxy)) {
DETACH_FROM_THREAD(thread_checker_);
DCHECK(proxy_thread_);
+ DCHECK(host_thread_);
DCHECK(proxy_);
- DCHECK(port_allocator_);
}
IceTransportHost::~IceTransportHost() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!HasConsumer());
}
-void IceTransportHost::Initialize(rtc::Thread* host_thread_rtc_thread) {
+void IceTransportHost::Initialize(
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component.
- if (!rtc::ThreadManager::Instance()->CurrentThread()) {
- rtc::ThreadManager::Instance()->SetCurrentThread(host_thread_rtc_thread);
- }
- // These settings are copied from PeerConnection:
- // https://codesearch.chromium.org/chromium/src/third_party/webrtc/pc/peerconnection.cc?l=4708&rcl=820ebd0f661696043959b5105b2814e0edd8b694
- port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
- port_allocator_->set_flags(port_allocator_->flags() |
- cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
- cricket::PORTALLOCATOR_ENABLE_IPV6 |
- cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
- port_allocator_->Initialize();
- transport_ = std::make_unique<cricket::P2PTransportChannel>(
- "", 0, port_allocator_.get());
- transport_->SignalGatheringState.connect(
- this, &IceTransportHost::OnGatheringStateChanged);
- transport_->SignalCandidateGathered.connect(
- this, &IceTransportHost::OnCandidateGathered);
- transport_->SignalStateChanged.connect(this,
- &IceTransportHost::OnStateChanged);
- // The ICE tiebreaker is used to determine which side is controlling/
- // controlled when both sides start in the same role. The number is randomly
- // generated so that each peer can calculate a.tiebreaker <= b.tiebreaker
- // consistently.
- transport_->SetIceTiebreaker(rtc::CreateRandomId64());
+ DCHECK(adapter_factory);
+ transport_ = adapter_factory->ConstructOnWorkerThread(this);
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> IceTransportHost::proxy_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return proxy_thread_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> IceTransportHost::host_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return host_thread_;
}
void IceTransportHost::StartGathering(
const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers,
const std::vector<cricket::RelayServerConfig>& turn_servers,
- int32_t candidate_filter) {
+ IceTransportPolicy policy) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- port_allocator_->set_candidate_filter(candidate_filter);
- port_allocator_->SetConfiguration(stun_servers, turn_servers,
- port_allocator_->candidate_pool_size(),
- port_allocator_->prune_turn_ports());
-
- transport_->SetIceParameters(local_parameters);
- transport_->MaybeStartGathering();
- DCHECK_EQ(transport_->gathering_state(), cricket::kIceGatheringGathering);
+ transport_->StartGathering(local_parameters, stun_servers, turn_servers,
+ policy);
}
-void IceTransportHost::SetRole(cricket::IceRole role) {
+void IceTransportHost::Start(
+ const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- transport_->SetIceRole(role);
+ transport_->Start(remote_parameters, role, initial_remote_candidates);
}
-void IceTransportHost::SetRemoteParameters(
- const cricket::IceParameters& remote_parameters) {
+void IceTransportHost::HandleRemoteRestart(
+ const cricket::IceParameters& new_remote_parameters) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- transport_->SetRemoteIceParameters(remote_parameters);
+ transport_->HandleRemoteRestart(new_remote_parameters);
}
void IceTransportHost::AddRemoteCandidate(const cricket::Candidate& candidate) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
transport_->AddRemoteCandidate(candidate);
+
+}
+
+bool IceTransportHost::HasConsumer() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return consumer_host_;
}
-void IceTransportHost::ClearRemoteCandidates() {
+IceTransportAdapter* IceTransportHost::ConnectConsumer(
+ QuicTransportHost* consumer_host) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- auto remote_candidates = transport_->remote_candidates();
- for (const auto& remote_candidate : remote_candidates) {
- transport_->RemoveRemoteCandidate(remote_candidate);
- }
+ DCHECK(consumer_host);
+ DCHECK(!consumer_host_);
+ consumer_host_ = consumer_host;
+ return transport_.get();
+}
+
+void IceTransportHost::DisconnectConsumer(QuicTransportHost* consumer_host) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(consumer_host);
+ DCHECK_EQ(consumer_host, consumer_host_);
+ consumer_host_ = nullptr;
}
void IceTransportHost::OnGatheringStateChanged(
- cricket::IceTransportInternal* transport) {
+ cricket::IceGatheringState new_state) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_EQ(transport, transport_.get());
PostCrossThreadTask(
*proxy_thread_, FROM_HERE,
CrossThreadBind(&IceTransportProxy::OnGatheringStateChanged, proxy_,
- transport_->gathering_state()));
+ new_state));
}
void IceTransportHost::OnCandidateGathered(
- cricket::IceTransportInternal* transport,
const cricket::Candidate& candidate) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_EQ(transport, transport_.get());
PostCrossThreadTask(*proxy_thread_, FROM_HERE,
CrossThreadBind(&IceTransportProxy::OnCandidateGathered,
proxy_, candidate));
}
-void IceTransportHost::OnStateChanged(
- cricket::IceTransportInternal* transport) {
+void IceTransportHost::OnStateChanged(cricket::IceTransportState new_state) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_EQ(transport, transport_.get());
- PostCrossThreadTask(*proxy_thread_, FROM_HERE,
- CrossThreadBind(&IceTransportProxy::OnStateChanged,
- proxy_, transport_->GetState()));
+ PostCrossThreadTask(
+ *proxy_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportProxy::OnStateChanged, proxy_, new_state));
+}
+
+void IceTransportHost::OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *proxy_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportProxy::OnSelectedCandidatePairChanged,
+ proxy_, selected_candidate_pair));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h
index 094130d2e91..9f78111ace8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h
@@ -9,15 +9,13 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
-#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
-
-namespace rtc {
-class Thread;
-}
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h"
namespace blink {
class IceTransportProxy;
+class QuicTransportHost;
// This class is the host side correspondent to the IceTransportProxy. See the
// IceTransportProxy documentation for background. This class lives on the host
@@ -41,38 +39,53 @@ class IceTransportProxy;
//
// The Host can be constructed on any thread but after that point all methods
// must be called on the host thread.
-class IceTransportHost final : public sigslot::has_slots<> {
+class IceTransportHost final : public IceTransportAdapter::Delegate {
public:
IceTransportHost(scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
- base::WeakPtr<IceTransportProxy> proxy,
- std::unique_ptr<cricket::PortAllocator> port_allocator);
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ base::WeakPtr<IceTransportProxy> proxy);
~IceTransportHost() override;
- void Initialize(rtc::Thread* host_thread_rtc_thread);
+ void Initialize(
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
+
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
void StartGathering(
const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers,
const std::vector<cricket::RelayServerConfig>& turn_servers,
- int32_t candidate_filter);
-
- void SetRole(cricket::IceRole role);
- void SetRemoteParameters(const cricket::IceParameters& remote_parameters);
-
+ IceTransportPolicy policy);
+ void Start(const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates);
+ void HandleRemoteRestart(const cricket::IceParameters& new_remote_parameters);
void AddRemoteCandidate(const cricket::Candidate& candidate);
- void ClearRemoteCandidates();
+
+ // A QuicTransportHost can be connected to this IceTransportHost. Only one can
+ // be connected at a time, and the caller must ensure that the consumer is
+ // disconnected before destroying the IceTransportHost.
+ // ConnectConsumer returns an implementation of IceTransportAdapter that
+ // should only be used on the host thread.
+ bool HasConsumer() const;
+ IceTransportAdapter* ConnectConsumer(QuicTransportHost* consumer_host);
+ void DisconnectConsumer(QuicTransportHost* consumer_host);
private:
- // Callbacks from P2PTransportChannel.
- void OnGatheringStateChanged(cricket::IceTransportInternal* transport);
- void OnCandidateGathered(cricket::IceTransportInternal* transport,
- const cricket::Candidate& candidate);
- void OnStateChanged(cricket::IceTransportInternal* transport);
+ // IceTransportAdapter::Delegate overrides.
+ void OnGatheringStateChanged(cricket::IceGatheringState new_state) override;
+ void OnCandidateGathered(const cricket::Candidate& candidate) override;
+ void OnStateChanged(cricket::IceTransportState new_state) override;
+ void OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) override;
const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_;
- std::unique_ptr<cricket::PortAllocator> port_allocator_;
- std::unique_ptr<cricket::P2PTransportChannel> transport_;
+ const scoped_refptr<base::SingleThreadTaskRunner> host_thread_;
+ std::unique_ptr<IceTransportAdapter> transport_;
base::WeakPtr<IceTransportProxy> proxy_;
+ QuicTransportHost* consumer_host_ = nullptr;
THREAD_CHECKER(thread_checker_);
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
index a8ab2c4e151..b1463372d2e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
@@ -13,11 +13,12 @@ namespace blink {
IceTransportProxy::IceTransportProxy(
FrameScheduler* frame_scheduler,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
- rtc::Thread* host_thread_rtc_thread,
Delegate* delegate,
- std::unique_ptr<cricket::PortAllocator> port_allocator)
- : host_thread_(std::move(host_thread)),
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory)
+ : proxy_thread_(std::move(proxy_thread)),
+ host_thread_(std::move(host_thread)),
host_(nullptr, base::OnTaskRunnerDeleter(host_thread_)),
delegate_(delegate),
connection_handle_for_scheduler_(
@@ -25,55 +26,71 @@ IceTransportProxy::IceTransportProxy(
weak_ptr_factory_(this) {
DCHECK(host_thread_);
DCHECK(delegate_);
- scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
- frame_scheduler->GetTaskRunner(TaskType::kNetworking);
- DCHECK(proxy_thread->BelongsToCurrentThread());
+ DCHECK(adapter_factory);
+ DCHECK(proxy_thread_->BelongsToCurrentThread());
+ adapter_factory->InitializeOnMainThread();
// Wait to initialize the host until the weak_ptr_factory_ is initialized.
// The IceTransportHost is constructed on the proxy thread but should only be
// interacted with via PostTask to the host thread. The OnTaskRunnerDeleter
// (configured above) will ensure it gets deleted on the host thread.
- host_.reset(new IceTransportHost(proxy_thread, weak_ptr_factory_.GetWeakPtr(),
- std::move(port_allocator)));
- PostCrossThreadTask(
- *host_thread_, FROM_HERE,
- CrossThreadBind(&IceTransportHost::Initialize,
- CrossThreadUnretained(host_.get()),
- CrossThreadUnretained(host_thread_rtc_thread)));
+ host_.reset(new IceTransportHost(proxy_thread_, host_thread_,
+ weak_ptr_factory_.GetWeakPtr()));
+ PostCrossThreadTask(*host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::Initialize,
+ CrossThreadUnretained(host_.get()),
+ WTF::Passed(std::move(adapter_factory))));
}
IceTransportProxy::~IceTransportProxy() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!HasConsumer());
// Note: The IceTransportHost will be deleted on the host thread.
}
+scoped_refptr<base::SingleThreadTaskRunner> IceTransportProxy::proxy_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return proxy_thread_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> IceTransportProxy::host_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return host_thread_;
+}
+
void IceTransportProxy::StartGathering(
const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers,
const std::vector<cricket::RelayServerConfig>& turn_servers,
- int32_t candidate_filter) {
+ IceTransportPolicy policy) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(
*host_thread_, FROM_HERE,
CrossThreadBind(&IceTransportHost::StartGathering,
CrossThreadUnretained(host_.get()), local_parameters,
- stun_servers, turn_servers, candidate_filter));
+ stun_servers, turn_servers, policy));
}
-void IceTransportProxy::SetRole(cricket::IceRole role) {
+void IceTransportProxy::Start(
+ const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
PostCrossThreadTask(
*host_thread_, FROM_HERE,
- CrossThreadBind(&IceTransportHost::SetRole,
- CrossThreadUnretained(host_.get()), role));
+ CrossThreadBind(&IceTransportHost::Start,
+ CrossThreadUnretained(host_.get()), remote_parameters,
+ role, initial_remote_candidates));
}
-void IceTransportProxy::SetRemoteParameters(
- const cricket::IceParameters& remote_parameters) {
+void IceTransportProxy::HandleRemoteRestart(
+ const cricket::IceParameters& new_remote_parameters) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- PostCrossThreadTask(
- *host_thread_, FROM_HERE,
- CrossThreadBind(&IceTransportHost::SetRemoteParameters,
- CrossThreadUnretained(host_.get()), remote_parameters));
+ PostCrossThreadTask(*host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::HandleRemoteRestart,
+ CrossThreadUnretained(host_.get()),
+ new_remote_parameters));
}
void IceTransportProxy::AddRemoteCandidate(
@@ -85,11 +102,25 @@ void IceTransportProxy::AddRemoteCandidate(
CrossThreadUnretained(host_.get()), candidate));
}
-void IceTransportProxy::ClearRemoteCandidates() {
+bool IceTransportProxy::HasConsumer() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- PostCrossThreadTask(*host_thread_, FROM_HERE,
- CrossThreadBind(&IceTransportHost::ClearRemoteCandidates,
- CrossThreadUnretained(host_.get())));
+ return consumer_proxy_;
+}
+
+IceTransportHost* IceTransportProxy::ConnectConsumer(
+ QuicTransportProxy* consumer_proxy) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(consumer_proxy);
+ DCHECK(!consumer_proxy_);
+ consumer_proxy_ = consumer_proxy;
+ return host_.get();
+}
+
+void IceTransportProxy::DisconnectConsumer(QuicTransportProxy* consumer_proxy) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(consumer_proxy);
+ DCHECK_EQ(consumer_proxy, consumer_proxy_);
+ consumer_proxy_ = nullptr;
}
void IceTransportProxy::OnGatheringStateChanged(
@@ -109,4 +140,11 @@ void IceTransportProxy::OnStateChanged(cricket::IceTransportState new_state) {
delegate_->OnStateChanged(new_state);
}
+void IceTransportProxy::OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnSelectedCandidatePairChanged(selected_candidate_pair);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h
index 10b3f33c286..d10b8666da0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h
@@ -9,6 +9,8 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
@@ -19,6 +21,7 @@ class Thread;
namespace blink {
class IceTransportHost;
+class QuicTransportProxy;
// This class allows the ICE implementation (P2PTransportChannel) to run on a
// thread different from the thread from which it is controlled. All
@@ -47,30 +50,46 @@ class IceTransportProxy final {
}
virtual void OnCandidateGathered(const cricket::Candidate& candidate) {}
virtual void OnStateChanged(cricket::IceTransportState new_state) {}
+ virtual void OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) {}
};
// Construct a Proxy with the underlying ICE implementation running on the
// given host thread and callbacks serviced by the given delegate.
// The P2PTransportChannel will be created with the given PortAllocator.
// The delegate must outlive the IceTransportProxy.
- IceTransportProxy(FrameScheduler* frame_scheduler,
- scoped_refptr<base::SingleThreadTaskRunner> host_thread,
- rtc::Thread* host_thread_rtc_thread,
- Delegate* delegate,
- std::unique_ptr<cricket::PortAllocator> port_allocator);
+ IceTransportProxy(
+ FrameScheduler* frame_scheduler,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ Delegate* delegate,
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
~IceTransportProxy();
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
+
+ // These methods are proxied to an IceTransportAdapter instance.
void StartGathering(
const cricket::IceParameters& local_parameters,
const cricket::ServerAddresses& stun_servers,
const std::vector<cricket::RelayServerConfig>& turn_servers,
- int32_t candidate_filter);
-
- void SetRole(cricket::IceRole role);
- void SetRemoteParameters(const cricket::IceParameters& remote_parameters);
-
+ IceTransportPolicy policy);
+ void Start(const cricket::IceParameters& remote_parameters,
+ cricket::IceRole role,
+ const std::vector<cricket::Candidate>& initial_remote_candidates);
+ void HandleRemoteRestart(const cricket::IceParameters& new_remote_parameters);
void AddRemoteCandidate(const cricket::Candidate& candidate);
- void ClearRemoteCandidates();
+
+ // A QuicTransportProxy can be connected to this IceTransportProxy. Only one
+ // can be connected at a time, and the caller must ensure that the consumer
+ // is disconnected before destroying the IceTransportProxy.
+ // ConnectConsumer returns an IceTransportHost that can be used to connect
+ // a QuicTransportHost.
+ bool HasConsumer() const;
+ IceTransportHost* ConnectConsumer(QuicTransportProxy* consumer_proxy);
+ void DisconnectConsumer(QuicTransportProxy* consumer_proxy);
private:
// Callbacks from RTCIceTransportHost.
@@ -78,12 +97,17 @@ class IceTransportProxy final {
void OnGatheringStateChanged(cricket::IceGatheringState new_state);
void OnCandidateGathered(const cricket::Candidate& candidate);
void OnStateChanged(cricket::IceTransportState new_state);
+ void OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair);
+ const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_;
const scoped_refptr<base::SingleThreadTaskRunner> host_thread_;
// Since the Host is deleted on the host thread (via OnTaskRunnerDeleter), as
// long as this is alive it is safe to post tasks to it (using unretained).
std::unique_ptr<IceTransportHost, base::OnTaskRunnerDeleter> host_;
Delegate* const delegate_;
+ QuicTransportProxy* consumer_proxy_ = nullptr;
// This handle notifies scheduler about an active connection associated
// with a frame. Handle should be destroyed when connection is closed.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h
new file mode 100644
index 00000000000..b9b76fe5f72
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h
@@ -0,0 +1,69 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_PACKET_TRANSPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_PACKET_TRANSPORT_H_
+
+#include "net/third_party/quic/core/quic_packet_writer.h"
+#include "net/third_party/quic/core/quic_types.h"
+#include "net/third_party/quic/platform/api/quic_export.h"
+
+namespace blink {
+
+// This is the interface for the underlying packet transport used by the
+// P2PQuicTransport for receiving and writing data. The standard
+// implementation of this interface uses an ICE transport.
+//
+// This object should be run entirely on the webrtc worker thread.
+class P2PQuicPacketTransport {
+ public:
+ // This is subclassed by the P2PQuicTransport so that it can receive incoming
+ // data. The standard case is for this to be the P2PQuicTransport.
+ // The P2PQuicPacketTransport will outlive the ReceiveDelegate.
+ class ReceiveDelegate {
+ public:
+ virtual ~ReceiveDelegate() = default;
+ virtual void OnPacketDataReceived(const char* data, size_t data_len) = 0;
+ };
+
+ // This is subclassed by the Writer, so that it is aware when the
+ // P2PQuicPacketTransport is ready to write data. The
+ // P2PQuicPacketTransport will outlive the WriteObserver.
+ class WriteObserver {
+ public:
+ virtual ~WriteObserver() = default;
+ virtual void OnCanWrite() = 0;
+ };
+
+ struct QuicPacket {
+ // This is taken from the quic::QuicConnection, and 0 means that it is not
+ // set. Packet numbers are used to provide metadata to the implementation of
+ // the P2PQuicPacketTransport, but this number is not used by the QUIC
+ // library itself.
+ quic::QuicPacketNumber packet_number;
+ const char* buffer;
+ size_t buf_len;
+ };
+
+ virtual ~P2PQuicPacketTransport() = default;
+
+ // Called by the P2PQuicPacketWriter (in quic_transport_factory_impl.cc) when
+ // writing QUIC packets to the network. Return the number of written bytes.
+ // Return 0 if the write is blocked.
+ virtual int WritePacket(const QuicPacket& packet) = 0;
+ // Sets the ReceiveDelegate for receiving packets.
+ // Since the ReceiveDelegate has a shorter lifetime than the
+ // P2PQuicPacketTransport, it must unset itself upon destruction.
+ virtual void SetReceiveDelegate(ReceiveDelegate* receive_delegate) = 0;
+ // Sets the WriteObserver for obsererving when it can write to the
+ // P2PQuicPacketTransport. Since the WriteObserver has a shorter lifetime than
+ // the P2PQuicPacketTransport, it must unset itself upon destruction.
+ virtual void SetWriteObserver(WriteObserver* write_observer) = 0;
+ // Returns true if the P2PQuicPacketTransport can write.
+ virtual bool Writable() = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_PACKET_TRANSPORT_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h
new file mode 100644
index 00000000000..a7ae56f2261
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h
@@ -0,0 +1,65 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
+
+namespace blink {
+
+// The bidirectional QUIC stream object to be used by the RTCQuicStream Web
+// API. See: https://w3c.github.io/webrtc-quic/#quicstream*
+//
+// Lifetime: The P2PQuicStream is owned by the P2PQuicTransport, and can be
+// deleted after the stream is closed for reading and writing. This can happen
+// in 3 ways: 1) OnRemoteReset has been fired. 2) Calling Reset(). 3) Both
+// Finish() has been called and OnRemoteFinish has been fired.
+class P2PQuicStream {
+ public:
+ // Receives callbacks for receiving RST_STREAM frames or a STREAM_FRAME with
+ // the FIN bit set. The Delegate should be subclassed by an object that can
+ // post the task to the main JS thread. The delegate's lifetime should outlive
+ // this P2PQuicStream.
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Called when the stream receives a RST_STREAM frame from the remote side.
+ // This means the stream is closed and can no longer read or write, and is
+ // deleted by the quic::QuicSession.
+ virtual void OnRemoteReset() {}
+
+ // Called when the P2PQuicStream has consumed all incoming data from the
+ // remote side up to the FIN bit. Consuming means that the data is marked
+ // as consumed by quic::QuicStreamSequencer, but the data has not
+ // necessarily been read by the application. If the stream has already
+ // finished writing, then upon consuming the FIN bit the stream can no
+ // longer read or write and is deleted by the quic::QuicSession.
+ virtual void OnRemoteFinish() {}
+ };
+
+ // Sends a RST_STREAM frame to the remote side. This closes the P2PQuicStream
+ // for reading & writing and it will be deleted by the quic::QuicSession. When
+ // the remote side receives the RST_STREAM frame it will close the stream for
+ // reading and writing and send a RST_STREAM frame back. Calling Reset() will
+ // not trigger OnRemoteReset to be called locally when the RST_STREAM frame is
+ // received from the remote side, because the local stream is already closed.
+ virtual void Reset() = 0;
+
+ // Sends a stream frame with the FIN bit set, which notifies the remote side
+ // that this stream is done writing. The stream can no longer write after
+ // calling this function. If the stream has already received a FIN bit, this
+ // will close the stream for reading & writing and it will be deleted by the
+ // quic::QuicSession.
+ virtual void Finish() = 0;
+
+ // Sets the delegate object, which must outlive the P2PQuicStream.
+ virtual void SetDelegate(Delegate* delegate) = 0;
+
+ // TODO:(https://crbug.com/874296): Create functions for reading and writing,
+ // specifically for waitForReadable/waitForWriteable.
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc
new file mode 100644
index 00000000000..ce6c4f4fda4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.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 "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h"
+
+#include "net/third_party/quic/core/quic_error_codes.h"
+
+namespace blink {
+
+P2PQuicStreamImpl::P2PQuicStreamImpl(quic::QuicStreamId id,
+ quic::QuicSession* session)
+ : quic::QuicStream(id, session, /*is_static=*/false, quic::BIDIRECTIONAL) {}
+
+P2PQuicStreamImpl::~P2PQuicStreamImpl() {}
+
+void P2PQuicStreamImpl::OnDataAvailable() {
+ // We just drop the data by marking all data as immediately consumed.
+ sequencer()->MarkConsumed(sequencer()->ReadableBytes());
+ if (sequencer()->IsClosed()) {
+ // This means all data has been consumed up to the FIN bit.
+ OnFinRead();
+ }
+}
+
+void P2PQuicStreamImpl::Reset() {
+ if (rst_sent()) {
+ // No need to reset twice. This could have already been sent as consequence
+ // of receiving a RST_STREAM frame.
+ return;
+ }
+ quic::QuicStream::Reset(quic::QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
+}
+
+void P2PQuicStreamImpl::Finish() {
+ // Should never call Finish twice.
+ DCHECK(!fin_sent());
+ quic::QuicStream::WriteOrBufferData("", /*fin=*/true, nullptr);
+}
+
+void P2PQuicStreamImpl::SetDelegate(P2PQuicStream::Delegate* delegate) {
+ delegate_ = delegate;
+}
+
+void P2PQuicStreamImpl::OnStreamReset(const quic::QuicRstStreamFrame& frame) {
+ // TODO(https://crbug.com/874296): If we get an incoming stream we need to
+ // make sure that the delegate is set before we have incoming data.
+ DCHECK(delegate_);
+ // Calling this on the QuicStream will ensure that the stream is closed
+ // for reading and writing and we send a RST frame to the remote side if
+ // we have not already.
+ quic::QuicStream::OnStreamReset(frame);
+ delegate_->OnRemoteReset();
+}
+
+void P2PQuicStreamImpl::OnFinRead() {
+ // TODO(https://crbug.com/874296): If we get an incoming stream we need to
+ // make sure that the delegate is set before we have incoming data.
+ DCHECK(delegate_);
+ // Calling this on the QuicStream ensures that the stream is closed
+ // for reading.
+ quic::QuicStream::OnFinRead();
+ delegate_->OnRemoteFinish();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h
new file mode 100644
index 00000000000..81cb68d02d0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
+
+#include "net/third_party/quic/core/quic_session.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h"
+
+namespace blink {
+
+class MODULES_EXPORT P2PQuicStreamImpl final : public P2PQuicStream,
+ public quic::QuicStream {
+ public:
+ P2PQuicStreamImpl(quic::QuicStreamId id, quic::QuicSession* session);
+ ~P2PQuicStreamImpl() override;
+
+ // QuicStream overrides.
+ //
+ // Right now this marks the data as consumed and drops it.
+ // TODO(https://crbug.com/874296): We need to update this function for
+ // reading and consuming data properly while the main JavaScript thread is
+ // busy. See:
+ // https://w3c.github.io/webrtc-quic/#dom-rtcquicstream-waitforreadable
+ void OnDataAvailable() override;
+
+ // P2PQuicStream overrides
+ void SetDelegate(P2PQuicStream::Delegate* delegate) override;
+
+ void Reset() override;
+
+ void Finish() override;
+
+ // quic::QuicStream overrides
+ //
+ // Called by the quic::QuicSession when receiving a RST_STREAM frame from the
+ // remote side. This closes the stream for reading & writing (if not already
+ // closed), and sends a RST_STREAM frame if one has not been sent yet.
+ void OnStreamReset(const quic::QuicRstStreamFrame& frame) override;
+
+ // Called when the stream has finished consumed data up to the FIN bit from
+ // the quic::QuicStreamSequencer. This will close the underlying QuicStream
+ // for reading. This can be called either by the P2PQuicStreamImpl when
+ // reading data, or by the quic::QuicStreamSequencer if we're done reading &
+ // receive a stream frame with the FIN bit.
+ void OnFinRead() override;
+
+ private:
+ using quic::QuicStream::Reset;
+ Delegate* delegate_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h
new file mode 100644
index 00000000000..ace4820ebcf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h
@@ -0,0 +1,77 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_
+
+#include "third_party/webrtc/rtc_base/sslfingerprint.h"
+
+namespace blink {
+
+class P2PQuicStream;
+
+// Used by the RTCQuicTransport Web API. This transport creates and manages
+// streams, handles negotiation, state changes and errors. Every
+// P2PQuicTransport function maps directly to a method in the RTCQuicTransport
+// Web API, i.e. RTCQuicTransport::stop() -->
+// P2PQuicTransport::Stop(). This allows posting just one task across
+// thread boundaries to execute a function.
+//
+// This object should be run entirely on the webrtc worker thread.
+class P2PQuicTransport {
+ public:
+ // Used for receiving callbacks from the P2PQuicTransport regarding QUIC
+ // connection changes, handshake success/failures and new QuicStreams being
+ // added from the remote side.
+ class Delegate {
+ public:
+ virtual ~Delegate() = default;
+ // Called when receiving a close frame from the remote side, due to
+ // calling P2PQuicTransport::Stop().
+ virtual void OnRemoteStopped() {}
+ // Called when the connection is closed due to a QUIC error. This can happen
+ // locally by the framer, or remotely by the peer.
+ virtual void OnConnectionFailed(const std::string& error_details,
+ bool from_remote) {}
+ // Called when the crypto handshake has completed and fingerprints have been
+ // verified.
+ virtual void OnConnected() {}
+
+ // Called when an incoming stream is received from the remote side. This
+ // stream is owned by the P2PQuicTransport. Its lifetime is managed by the
+ // P2PQuicTransport, and can be deleted when:
+ // - The P2PQuicStream becomes closed for reading and writing.
+ // - Stop() is called.
+ // - The P2PQuicTransport is deleted.
+ virtual void OnStream(P2PQuicStream* stream) {}
+ };
+
+ virtual ~P2PQuicTransport() = default;
+
+ // Closes the QuicConnection and sends a close frame to the remote side.
+ // This will trigger P2PQuicTransport::Delegate::OnRemoteClosed() on the
+ // remote side.
+ virtual void Stop() = 0;
+
+ // Starts the QUIC handshake negotiation and sets the remote fingerprints
+ // that were signaled through a secure channel. These fingerprints are used to
+ // verify the self signed remote certificate used in the QUIC handshake. See:
+ // https://w3c.github.io/webrtc-quic/#quic-transport*
+ virtual void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>>
+ remote_fingerprints) = 0;
+
+ // Creates a new outgoing stream. This stream is owned by the
+ // P2PQuicTransport. Its lifetime is managed by the P2PQuicTransport,
+ // and can be deleted when:
+ // - The P2PQuicStream becomes closed for reading and writing.
+ // - Stop() is called.
+ // - The P2PQuicTransport is deleted.
+ virtual P2PQuicStream* CreateStream() = 0;
+
+ // TODO(https://crbug.com/874296): Consider adding a getter for the
+ // local fingerprints of the certificate(s) set in the constructor.
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h
new file mode 100644
index 00000000000..a6c67feb4d8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h
@@ -0,0 +1,73 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_H_
+
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
+#include "third_party/webrtc/rtc_base/rtccertificate.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace blink {
+
+// A simple config object for creating a P2PQuicTransport. It's constructor
+// guarantees that the required objects for creating a P2PQuicTransport are part
+// of the P2PQuicTransportConfig.
+struct P2PQuicTransportConfig final {
+ // This object is only moveable.
+ explicit P2PQuicTransportConfig(
+ P2PQuicTransport::Delegate* const delegate_in,
+ P2PQuicPacketTransport* const packet_transport_in,
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>
+ certificates_in)
+ : packet_transport(packet_transport_in),
+ certificates(certificates_in),
+ delegate(delegate_in) {
+ DCHECK_GT(certificates.size(), 0u);
+ DCHECK(packet_transport);
+ DCHECK(delegate);
+ }
+ P2PQuicTransportConfig(const P2PQuicTransportConfig&) = delete;
+ P2PQuicTransportConfig& operator=(const P2PQuicTransportConfig&) = delete;
+ P2PQuicTransportConfig(P2PQuicTransportConfig&&) = default;
+ P2PQuicTransportConfig& operator=(P2PQuicTransportConfig&&) = delete;
+ ~P2PQuicTransportConfig() = default;
+
+ // The standard case is an ICE transport. It's lifetime will be managed by
+ // the ICE transport objects and outlive the P2PQuicTransport.
+ P2PQuicPacketTransport* const packet_transport;
+ bool is_server = true;
+ // The certificates are owned by the P2PQuicTransport. These come from
+ // blink::RTCCertificates: https://www.w3.org/TR/webrtc/#dom-rtccertificate
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
+ // Mandatory for creating a P2PQuicTransport and must outlive
+ // the P2PQuicTransport. In the standard case the |delegate_| will be
+ // the object that owns the P2PQuicTransport.
+ P2PQuicTransport::Delegate* const delegate;
+ // When set to true the P2PQuicTransport will immediately be able
+ // to listen and respond to a crypto handshake upon construction.
+ // This will NOT start a handshake.
+ bool can_respond_to_crypto_handshake = true;
+};
+
+// For creating a P2PQuicTransport. This factory should be injected into
+// whichever object plans to own and use a P2PQuicTransport. The
+// P2PQuicTransportFactory needs to outlive the P2PQuicTransport it creates.
+//
+// This object should be run entirely on the webrtc worker thread.
+class P2PQuicTransportFactory {
+ public:
+ virtual ~P2PQuicTransportFactory() = default;
+
+ // Creates the P2PQuicTransport. This should be called on the same
+ // thread that the P2PQuicTransport will be used on.
+ virtual std::unique_ptr<P2PQuicTransport> CreateQuicTransport(
+ P2PQuicTransportConfig config) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.cc
new file mode 100644
index 00000000000..73e4c3a649a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.cc
@@ -0,0 +1,194 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h"
+#include "net/third_party/quic/core/quic_packet_writer.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h"
+#include "third_party/webrtc/rtc_base/rtccertificate.h"
+
+namespace blink {
+
+namespace {
+
+// The P2PQuicPacketWriter is a private helper class that implements the
+// QuicPacketWriter using a P2PQuicPacketTransport. This allows us to
+// connect our own packet transport for writing into the QuicConnection.
+// The normal case is using an ICE transport (packet_transport) for writing.
+class P2PQuicPacketWriter : public quic::QuicPacketWriter,
+ public P2PQuicPacketTransport::WriteObserver {
+ public:
+ P2PQuicPacketWriter(P2PQuicPacketTransport* packet_transport)
+ : packet_transport_(packet_transport) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(packet_transport_);
+ packet_transport_->SetWriteObserver(this);
+ }
+
+ // This way the packet transport knows it no longer has a write observer and
+ // can DCHECK this on destruction.
+ ~P2PQuicPacketWriter() override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ packet_transport_->SetWriteObserver(nullptr);
+ }
+
+ // Sets the QuicConnection (which owns this packet writer). This allows us
+ // to get the packet numbers of QUIC packets we write. The QuicConnection
+ // is created with a quic::QuicPacketWriter, so we can't set the connection
+ // in the constructor.
+ void InitializeWithQuicConnection(quic::QuicConnection* connection) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(connection);
+ if (packet_transport_->Writable()) {
+ SetWritable();
+ }
+ connection_ = connection;
+ }
+
+ // quic::QuicPacketWriter overrides.
+
+ // Writes a QUIC packet to the network with the packet number as additional
+ // packet info.
+ quic::WriteResult WritePacket(const char* buffer,
+ size_t buf_len,
+ const quic::QuicIpAddress& self_address,
+ const quic::QuicSocketAddress& peer_address,
+ quic::PerPacketOptions* options) override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(connection_);
+ if (IsWriteBlocked()) {
+ return quic::WriteResult(quic::WRITE_STATUS_BLOCKED, EWOULDBLOCK);
+ }
+
+ P2PQuicPacketTransport::QuicPacket packet;
+ packet.packet_number = connection_->packet_generator().packet_number();
+ packet.buffer = buffer;
+ packet.buf_len = buf_len;
+ int bytes_written = packet_transport_->WritePacket(packet);
+ if (bytes_written <= 0) {
+ writable_ = false;
+ return quic::WriteResult(quic::WRITE_STATUS_BLOCKED, EWOULDBLOCK);
+ }
+ return quic::WriteResult(quic::WRITE_STATUS_OK, bytes_written);
+ }
+
+ bool IsWriteBlockedDataBuffered() const override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return false;
+ }
+
+ bool IsWriteBlocked() const override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return !writable_;
+ }
+
+ quic::QuicByteCount GetMaxPacketSize(
+ const quic::QuicSocketAddress& peer_address) const override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // This can be configured later.
+ return 1200;
+ }
+
+ void SetWritable() override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ writable_ = true;
+ }
+
+ bool SupportsReleaseTime() const override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return false;
+ }
+
+ bool IsBatchMode() const override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return false;
+ }
+
+ char* GetNextWriteLocation(
+ const quic::QuicIpAddress& self_address,
+ const quic::QuicSocketAddress& peer_address) override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return nullptr;
+ }
+
+ quic::WriteResult Flush() override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return quic::WriteResult(quic::WRITE_STATUS_OK, 0);
+ }
+
+ // P2PQuicPacketTransport::WriteDelegate override.
+ void OnCanWrite() override {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SetWritable();
+ connection_->OnCanWrite();
+ }
+
+ private:
+ // The packet transport is owned by the P2PQuicSession, not the
+ // BlinkPacketWriter.
+ P2PQuicPacketTransport* packet_transport_;
+ // The QuicConnection owns this packet writer and will outlive it.
+ quic::QuicConnection* connection_;
+
+ bool writable_ = false;
+ THREAD_CHECKER(thread_checker_);
+};
+
+// Creates the QuicConnection for the QuicSession. Currently this connection
+// uses a dummy address and ID. The |packet_writer| is a basic implementation
+// using the QuicTransportConfig::packet_transport for writing. The |helper|
+// and |alarm_factory| should be chromium specific implementations.
+std::unique_ptr<quic::QuicConnection> CreateQuicConnection(
+ bool is_server,
+ quic::QuicConnectionHelperInterface* helper,
+ quic::QuicPacketWriter* packet_writer,
+ quic::QuicAlarmFactory* alarm_factory) {
+ quic::QuicIpAddress ip;
+ ip.FromString("0.0.0.0");
+ quic::QuicSocketAddress dummy_address(ip, 0 /* Port */);
+ quic::Perspective perspective =
+ is_server ? quic::Perspective::IS_SERVER : quic::Perspective::IS_CLIENT;
+ return std::make_unique<quic::QuicConnection>(
+ 0 /* dummy ID */, dummy_address, helper, alarm_factory, packet_writer,
+ /* owns_writer */ true, perspective, quic::CurrentSupportedVersions());
+}
+} // namespace
+
+P2PQuicTransportFactoryImpl::P2PQuicTransportFactoryImpl(
+ quic::QuicClock* clock,
+ std::unique_ptr<quic::QuicAlarmFactory> alarm_factory)
+ : clock_(clock), alarm_factory_(std::move(alarm_factory)) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+// The P2PQuicTransportImpl is created with Chromium specific QUIC objects:
+// QuicClock, QuicRandom, QuicConnectionHelper and QuicAlarmFactory.
+std::unique_ptr<P2PQuicTransport>
+P2PQuicTransportFactoryImpl::CreateQuicTransport(
+ P2PQuicTransportConfig config) {
+ DCHECK(config.packet_transport);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ quic::QuicRandom* quic_random = quic::QuicRandom::GetInstance();
+ // The P2PQuicSession owns these chromium specific objects required
+ // by the QuicConnection. These outlive the QuicConnection itself.
+ std::unique_ptr<net::QuicChromiumConnectionHelper> helper =
+ std::make_unique<net::QuicChromiumConnectionHelper>(clock_, quic_random);
+
+ P2PQuicPacketWriter* packet_writer =
+ new P2PQuicPacketWriter(config.packet_transport);
+ std::unique_ptr<quic::QuicConnection> quic_connection = CreateQuicConnection(
+ config.is_server, helper.get(), packet_writer, alarm_factory_.get());
+ // It's okay for the quic::QuicConnection to have a P2PQuicPacketWriter before
+ // the P2PQuicPacketWriter is initialized, because the P2QuicPacketWriter
+ // won't be writable until this occurs.
+ packet_writer->InitializeWithQuicConnection(quic_connection.get());
+
+ // QUIC configurations for the session are specified here.
+ quic::QuicConfig quic_config;
+ return std::make_unique<P2PQuicTransportImpl>(
+ std::move(config), std::move(helper), std::move(quic_connection),
+ quic_config, clock_);
+}
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h
new file mode 100644
index 00000000000..6bc83546ab8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_IMPL_H_
+
+#include "net/third_party/quic/core/quic_connection.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h"
+
+namespace blink {
+
+// For creating a P2PQuicTransportImpl to be used for the blink Web API -
+// RTCQuicTransport.
+//
+// This object should be run entirely on the webrtc worker thread.
+class MODULES_EXPORT P2PQuicTransportFactoryImpl final
+ : public P2PQuicTransportFactory {
+ public:
+ P2PQuicTransportFactoryImpl(
+ quic::QuicClock* clock,
+ std::unique_ptr<quic::QuicAlarmFactory> alarm_factory);
+ ~P2PQuicTransportFactoryImpl() override {}
+
+ // QuicTransportFactoryInterface override.
+ std::unique_ptr<P2PQuicTransport> CreateQuicTransport(
+ P2PQuicTransportConfig config) override;
+
+ private:
+ // This is used to create a QuicChromiumConnectionHelper for the session.
+ // Should outlive the P2PQuicTransportFactoryImpl.
+ quic::QuicClock* clock_;
+ // Used for alarms that drive the underlying QUIC library. Should use the same
+ // clock as |clock_|.
+ std::unique_ptr<quic::QuicAlarmFactory> alarm_factory_;
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_FACTORY_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
new file mode 100644
index 00000000000..fe216c251e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
@@ -0,0 +1,355 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h"
+
+#include "net/quic/quic_chromium_connection_helper.h"
+#include "net/third_party/quic/core/crypto/proof_source.h"
+#include "net/third_party/quic/core/crypto/quic_random.h"
+#include "net/third_party/quic/core/quic_config.h"
+#include "net/third_party/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quic/core/tls_server_handshaker.h"
+#include "net/third_party/quic/tools/quic_simple_crypto_server_stream_helper.h"
+
+namespace blink {
+
+namespace {
+
+static const char kClosingDetails[] = "Application closed connection.";
+static const size_t kHostnameLength = 32;
+
+// TODO(https://crbug.com/874300): Create a secure connection by implementing a
+// P2PProofSource and P2PProofVerifier and remove these once the TLS 1.3
+// handshake is implemented for QUIC. This will allow us to verify for both the
+// server and client:
+// - The self signed certificate fingerprint matches the remote
+// fingerprint that was signaled.
+// - The peer owns the certificate, by verifying the signature of the hash of
+// the handshake context.
+//
+// Used by QuicCryptoServerConfig to provide dummy proof credentials
+// (taken from quic/quartc).
+class DummyProofSource : public quic::ProofSource {
+ public:
+ DummyProofSource() {}
+ ~DummyProofSource() override {}
+
+ // ProofSource override.
+ void GetProof(const quic::QuicSocketAddress& server_addr,
+ const quic::QuicString& hostname,
+ const quic::QuicString& server_config,
+ quic::QuicTransportVersion transport_version,
+ quic::QuicStringPiece chlo_hash,
+ std::unique_ptr<Callback> callback) override {
+ quic::QuicReferenceCountedPointer<ProofSource::Chain> chain;
+ quic::QuicCryptoProof proof;
+ std::vector<quic::QuicString> certs;
+ certs.push_back("Dummy cert");
+ chain = new ProofSource::Chain(certs);
+ proof.signature = "Dummy signature";
+ proof.leaf_cert_scts = "Dummy timestamp";
+ callback->Run(true, chain, proof, nullptr /* details */);
+ }
+
+ quic::QuicReferenceCountedPointer<Chain> GetCertChain(
+ const quic::QuicSocketAddress& server_address,
+ const quic::QuicString& hostname) override {
+ return quic::QuicReferenceCountedPointer<Chain>();
+ }
+
+ void ComputeTlsSignature(
+ const quic::QuicSocketAddress& server_address,
+ const quic::QuicString& hostname,
+ uint16_t signature_algorithm,
+ quic::QuicStringPiece in,
+ std::unique_ptr<SignatureCallback> callback) override {
+ callback->Run(true, "Dummy signature");
+ }
+};
+
+// Used by QuicCryptoClientConfig to ignore the peer's credentials
+// and establish an insecure QUIC connection (taken from quic/quartc).
+class InsecureProofVerifier : public quic::ProofVerifier {
+ public:
+ InsecureProofVerifier() {}
+ ~InsecureProofVerifier() override {}
+
+ // ProofVerifier override.
+ quic::QuicAsyncStatus VerifyProof(
+ const quic::QuicString& hostname,
+ const uint16_t port,
+ const quic::QuicString& server_config,
+ quic::QuicTransportVersion transport_version,
+ quic::QuicStringPiece chlo_hash,
+ const std::vector<quic::QuicString>& certs,
+ const quic::QuicString& cert_sct,
+ const quic::QuicString& signature,
+ const quic::ProofVerifyContext* context,
+ quic::QuicString* error_details,
+ std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
+ std::unique_ptr<quic::ProofVerifierCallback> callback) override {
+ return quic::QUIC_SUCCESS;
+ }
+
+ quic::QuicAsyncStatus VerifyCertChain(
+ const quic::QuicString& hostname,
+ const std::vector<quic::QuicString>& certs,
+ const quic::ProofVerifyContext* context,
+ quic::QuicString* error_details,
+ std::unique_ptr<quic::ProofVerifyDetails>* details,
+ std::unique_ptr<quic::ProofVerifierCallback> callback) override {
+ return quic::QUIC_SUCCESS;
+ }
+
+ std::unique_ptr<quic::ProofVerifyContext> CreateDefaultContext() override {
+ return nullptr;
+ }
+};
+
+// A dummy helper for a server crypto stream that accepts all client hellos
+// and generates a random connection ID.
+class DummyCryptoServerStreamHelper
+ : public quic::QuicCryptoServerStream::Helper {
+ public:
+ explicit DummyCryptoServerStreamHelper(quic::QuicRandom* random)
+ : random_(random) {}
+ ~DummyCryptoServerStreamHelper() override {}
+
+ quic::QuicConnectionId GenerateConnectionIdForReject(
+ quic::QuicConnectionId connection_id) const override {
+ return random_->RandUint64();
+ }
+
+ bool CanAcceptClientHello(const quic::CryptoHandshakeMessage& message,
+ const quic::QuicSocketAddress& client_address,
+ const quic::QuicSocketAddress& peer_address,
+ const quic::QuicSocketAddress& self_address,
+ quic::QuicString* error_details) const override {
+ return true;
+ }
+
+ private:
+ // Used to generate random connection IDs. Needs to outlive this.
+ quic::QuicRandom* random_;
+};
+} // namespace
+
+P2PQuicTransportImpl::P2PQuicTransportImpl(
+ P2PQuicTransportConfig p2p_transport_config,
+ std::unique_ptr<net::QuicChromiumConnectionHelper> helper,
+ std::unique_ptr<quic::QuicConnection> connection,
+ const quic::QuicConfig& quic_config,
+ quic::QuicClock* clock)
+ : quic::QuicSession(connection.get(), nullptr /* visitor */, quic_config),
+ helper_(std::move(helper)),
+ connection_(std::move(connection)),
+ perspective_(p2p_transport_config.is_server
+ ? quic::Perspective::IS_SERVER
+ : quic::Perspective::IS_CLIENT),
+ packet_transport_(p2p_transport_config.packet_transport),
+ delegate_(p2p_transport_config.delegate),
+ clock_(clock) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ DCHECK(clock_);
+ DCHECK(packet_transport_);
+ DCHECK_GT(p2p_transport_config.certificates.size(), 0u);
+ if (p2p_transport_config.can_respond_to_crypto_handshake) {
+ InitializeCryptoStream();
+ }
+ // TODO(https://crbug.com/874296): The web API accepts multiple certificates,
+ // and we might want to pass these down to let QUIC decide on what to use.
+ certificate_ = p2p_transport_config.certificates[0];
+ packet_transport_->SetReceiveDelegate(this);
+}
+
+P2PQuicTransportImpl::~P2PQuicTransportImpl() {
+ packet_transport_->SetReceiveDelegate(nullptr);
+}
+
+void P2PQuicTransportImpl::Stop() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (IsClosed()) {
+ return;
+ }
+ // The error code used for the connection closing is
+ // quic::QUIC_CONNECTION_CANCELLED. This allows us to distinguish that the
+ // application closed the connection, as opposed to it closing from a
+ // failure/error.
+ connection_->CloseConnection(
+ quic::QuicErrorCode::QUIC_CONNECTION_CANCELLED, kClosingDetails,
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+}
+
+void P2PQuicTransportImpl::Start(
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(remote_fingerprints_.size(), 0u);
+ DCHECK_GT(remote_fingerprints.size(), 0u);
+ if (IsClosed()) {
+ // We could have received a close from the remote side before calling this.
+ return;
+ }
+ // These will be used to verify the remote certificate during the handshake.
+ remote_fingerprints_ = std::move(remote_fingerprints);
+
+ if (perspective_ == quic::Perspective::IS_CLIENT) {
+ quic::QuicCryptoClientStream* client_crypto_stream =
+ static_cast<quic::QuicCryptoClientStream*>(crypto_stream_.get());
+ client_crypto_stream->CryptoConnect();
+ }
+}
+
+void P2PQuicTransportImpl::OnPacketDataReceived(const char* data,
+ size_t data_len) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Received data from the |packet_transport_|. Create a QUIC packet and send
+ // it to be processed by the QuicSession/Connection.
+ quic::QuicReceivedPacket packet(data, data_len, clock_->Now());
+ ProcessUdpPacket(connection()->self_address(), connection()->peer_address(),
+ packet);
+}
+
+quic::QuicCryptoStream* P2PQuicTransportImpl::GetMutableCryptoStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return crypto_stream_.get();
+}
+
+const quic::QuicCryptoStream* P2PQuicTransportImpl::GetCryptoStream() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return crypto_stream_.get();
+}
+
+P2PQuicStreamImpl* P2PQuicTransportImpl::CreateStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return CreateOutgoingBidirectionalStream();
+}
+
+P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingBidirectionalStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ P2PQuicStreamImpl* stream = CreateStreamInternal(GetNextOutgoingStreamId());
+ ActivateStream(std::unique_ptr<P2PQuicStreamImpl>(stream));
+ return stream;
+}
+
+P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingUnidirectionalStream() {
+ DCHECK(false);
+ return nullptr;
+}
+
+P2PQuicStreamImpl* P2PQuicTransportImpl::CreateIncomingDynamicStream(
+ quic::QuicStreamId id) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ P2PQuicStreamImpl* stream = CreateStreamInternal(id);
+ ActivateStream(std::unique_ptr<P2PQuicStreamImpl>(stream));
+ delegate_->OnStream(stream);
+ return stream;
+}
+
+P2PQuicStreamImpl* P2PQuicTransportImpl::CreateStreamInternal(
+ quic::QuicStreamId id) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(crypto_stream_);
+ DCHECK(IsEncryptionEstablished());
+ DCHECK(!IsClosed());
+ return new P2PQuicStreamImpl(id, this);
+}
+
+void P2PQuicTransportImpl::InitializeCryptoStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!crypto_stream_);
+ switch (perspective_) {
+ case quic::Perspective::IS_CLIENT: {
+ if (!crypto_client_config_) {
+ // The |crypto_client_config_| has not already been set (by the test).
+ std::unique_ptr<quic::ProofVerifier> proof_verifier(
+ new InsecureProofVerifier);
+ crypto_client_config_ = std::make_unique<quic::QuicCryptoClientConfig>(
+ std::move(proof_verifier),
+ quic::TlsClientHandshaker::CreateSslCtx());
+ }
+ // The host must be unique for every endpoint the client communicates
+ // with.
+ char random_hostname[kHostnameLength];
+ helper_->GetRandomGenerator()->RandBytes(random_hostname,
+ kHostnameLength);
+ quic::QuicServerId server_id(
+ /*host=*/quic::QuicString(random_hostname, kHostnameLength),
+ /*port=*/0,
+ /*privacy_mode_enabled=*/false);
+ crypto_stream_ = std::make_unique<quic::QuicCryptoClientStream>(
+ server_id, /*QuicSession=*/this,
+ crypto_client_config_->proof_verifier()->CreateDefaultContext(),
+ crypto_client_config_.get(), /*ProofHandler=*/this);
+ QuicSession::Initialize();
+ break;
+ }
+ case quic::Perspective::IS_SERVER: {
+ std::unique_ptr<quic::ProofSource> proof_source(new DummyProofSource);
+ crypto_server_config_ = std::make_unique<quic::QuicCryptoServerConfig>(
+ quic::QuicCryptoServerConfig::TESTING, helper_->GetRandomGenerator(),
+ std::move(proof_source), quic::KeyExchangeSource::Default(),
+ quic::TlsServerHandshaker::CreateSslCtx());
+ // Provide server with serialized config string to prove ownership.
+ quic::QuicCryptoServerConfig::ConfigOptions options;
+ // The |message| is used to handle the return value of AddDefaultConfig
+ // which is raw pointer of the CryptoHandshakeMessage.
+ std::unique_ptr<quic::CryptoHandshakeMessage> message(
+ crypto_server_config_->AddDefaultConfig(
+ helper_->GetRandomGenerator(), helper_->GetClock(), options));
+ compressed_certs_cache_.reset(new quic::QuicCompressedCertsCache(
+ quic::QuicCompressedCertsCache::kQuicCompressedCertsCacheSize));
+ bool use_stateless_rejects_if_peer_supported = false;
+ server_stream_helper_ = std::make_unique<DummyCryptoServerStreamHelper>(
+ helper_->GetRandomGenerator());
+
+ crypto_stream_ = std::make_unique<quic::QuicCryptoServerStream>(
+ crypto_server_config_.get(), compressed_certs_cache_.get(),
+ use_stateless_rejects_if_peer_supported, this,
+ server_stream_helper_.get());
+ QuicSession::Initialize();
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void P2PQuicTransportImpl::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ QuicSession::OnCryptoHandshakeEvent(event);
+ if (event == HANDSHAKE_CONFIRMED) {
+ DCHECK(IsEncryptionEstablished());
+ DCHECK(IsCryptoHandshakeConfirmed());
+ delegate_->OnConnected();
+ }
+}
+
+void P2PQuicTransportImpl::OnConnectionClosed(
+ quic::QuicErrorCode error,
+ const std::string& error_details,
+ quic::ConnectionCloseSource source) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ quic::QuicSession::OnConnectionClosed(error, error_details, source);
+ if (error != quic::QuicErrorCode::QUIC_CONNECTION_CANCELLED) {
+ delegate_->OnConnectionFailed(
+ error_details, source == quic::ConnectionCloseSource::FROM_PEER);
+ } else if (source == quic::ConnectionCloseSource::FROM_PEER) {
+ // This connection was closed by the application of the remote side.
+ delegate_->OnRemoteStopped();
+ }
+}
+
+bool P2PQuicTransportImpl::IsClosed() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return !connection_->connected();
+}
+
+void P2PQuicTransportImpl::set_crypto_client_config(
+ std::unique_ptr<quic::QuicCryptoClientConfig> crypto_client_config) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ crypto_client_config_ = std::move(crypto_client_config);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
new file mode 100644
index 00000000000..609f223cc98
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
@@ -0,0 +1,180 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_IMPL_H_
+
+#include "base/threading/thread_checker.h"
+#include "net/quic/quic_chromium_connection_helper.h"
+#include "net/third_party/quic/core/crypto/quic_crypto_client_config.h"
+#include "net/third_party/quic/core/crypto/quic_crypto_server_config.h"
+#include "net/third_party/quic/core/quic_crypto_client_stream.h"
+#include "net/third_party/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quic/core/quic_packet_writer.h"
+#include "net/third_party/quic/core/quic_session.h"
+#include "net/third_party/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h"
+#include "third_party/webrtc/rtc_base/rtccertificate.h"
+
+namespace blink {
+
+// The P2PQuicTransportImpl subclasses the quic::QuicSession in order to expose
+// QUIC as a P2P transport. This specific subclass implements the crypto
+// handshake for a peer to peer connection, which requires verifying the remote
+// certificate's fingerprint, but otherwise exposes a raw quic::QuicSession.
+//
+// At a high level, the quic::QuicConnection manages the actual connection
+// between two endpoints, while the quic::QuicSession owns and manages the
+// quic::QuicStreams. The quic::QuicSession also handles the negotiation between
+// endpoints, session control (reset, window updates, control frames, etc.), and
+// callbacks from either the connection (quic::QuicConnectionVisitorInterface),
+// frames being acked or lost (quic::SessionNotifierInterface), or handshake
+// state changes.
+//
+// This object should be run entirely on the webrtc worker thread.
+class MODULES_EXPORT P2PQuicTransportImpl final
+ : public quic::QuicSession,
+ public P2PQuicTransport,
+ public P2PQuicPacketTransport::ReceiveDelegate,
+ public quic::QuicCryptoClientStream::ProofHandler {
+ public:
+ P2PQuicTransportImpl(
+ P2PQuicTransportConfig p2p_transport_config,
+ std::unique_ptr<net::QuicChromiumConnectionHelper> helper,
+ std::unique_ptr<quic::QuicConnection> connection,
+ const quic::QuicConfig& quic_config,
+ quic::QuicClock* clock);
+
+ ~P2PQuicTransportImpl() override;
+
+ // P2PQuicTransport overrides.
+
+ void Stop() override;
+
+ // Sets the remote fingerprints, and if the the P2PQuicTransportImpl is a
+ // client starts the QUIC handshake . This handshake is currently insecure,
+ // meaning that the certificates used are fake and are not verified. It also
+ // assumes a handshake for a server/client case. This must be called before
+ // creating any streams.
+ //
+ // TODO(https://crbug.com/874300): Verify both the client and server
+ // certificates with the signaled remote fingerprints. Until the TLS 1.3
+ // handshake is supported in the QUIC core library we can only verify the
+ // server's certificate, but not the client's. Note that this means
+ // implementing the handshake for a P2P case, in which case verification
+ // completes after both receiving the signaled remote fingerprint and getting
+ // a client hello. Because either can come first, a synchronous call to verify
+ // the remote fingerprint is not possible.
+ void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>>
+ remote_fingerprints) override;
+
+ // Creates an outgoing stream that is owned by the quic::QuicSession.
+ P2PQuicStreamImpl* CreateStream() override;
+
+ // P2PQuicPacketTransport::Delegate override.
+ void OnPacketDataReceived(const char* data, size_t data_len) override;
+
+ // quic::QuicCryptoClientStream::ProofHandler overrides used in a client
+ // connection to get certificate verification details.
+
+ // Called when the proof verification completes. This information is used
+ // for 0 RTT handshakes, which isn't relevant for our P2P handshake.
+ void OnProofValid(
+ const quic::QuicCryptoClientConfig::CachedState& cached) override{};
+
+ // Called when proof verification become available.
+ void OnProofVerifyDetailsAvailable(
+ const quic::ProofVerifyDetails& verify_details) override{};
+
+ // quic::QuicConnectionVisitorInterface override.
+ void OnConnectionClosed(quic::QuicErrorCode error,
+ const std::string& error_details,
+ quic::ConnectionCloseSource source) override;
+
+ protected:
+ // quic::QuicSession overrides.
+ // TODO(https://crbug.com/874296): Subclass QuicStream and implement these
+ // functions.
+
+ // Creates a new stream initiated from the remote side. The caller does not
+ // own the stream, so the stream is activated and ownership is moved to the
+ // quic::QuicSession.
+ P2PQuicStreamImpl* CreateIncomingDynamicStream(
+ quic::QuicStreamId id) override;
+
+ // Creates a new outgoing stream. The caller does not own the
+ // stream, so the stream is activated and ownership is moved to the
+ // quic::QuicSession.
+ P2PQuicStreamImpl* CreateOutgoingBidirectionalStream() override;
+ P2PQuicStreamImpl* CreateOutgoingUnidirectionalStream() override;
+
+ void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
+
+ private:
+ // This is for testing connection failures and handshake failures.
+ friend class P2PQuicTransportTest;
+
+ // These functions are used for testing.
+ //
+ // Returns true if the quic::QuicConnection has been closed remotely or
+ // locally.
+ bool IsClosed();
+ quic::QuicConnection* connection() { return connection_.get(); }
+ // Allows the test to set its own proof verification.
+ void set_crypto_client_config(
+ std::unique_ptr<quic::QuicCryptoClientConfig> crypto_client_config);
+
+ // quic::QuicSession overrides.
+ const quic::QuicCryptoStream* GetCryptoStream() const override;
+ quic::QuicCryptoStream* GetMutableCryptoStream() override;
+
+ // Creates the crypto stream necessary for handshake negotiation, and
+ // initializes the parent class (quic::QuicSession). This must be called on
+ // both sides before communicating between endpoints (Start, Close, etc.).
+ void InitializeCryptoStream();
+
+ // Creates a new stream. This helper function is used when we need to create
+ // a new incoming stream or outgoing stream.
+ P2PQuicStreamImpl* CreateStreamInternal(quic::QuicStreamId id);
+
+ // The server_config and client_config are used for setting up the crypto
+ // connection. The ownership of these objects or the objects they own
+ // (quic::ProofSource, quic::ProofVerifier, etc.), are not passed on to the
+ // QUIC library for the handshake, so we must own them here. A client
+ // |perspective_| will not have a crypto_server_config and vice versa.
+ std::unique_ptr<quic::QuicCryptoServerConfig> crypto_server_config_;
+ std::unique_ptr<quic::QuicCryptoClientConfig> crypto_client_config_;
+ // Used by server |crypto_stream_| to track most recently compressed certs.
+ std::unique_ptr<quic::QuicCompressedCertsCache> compressed_certs_cache_;
+ std::unique_ptr<quic::QuicCryptoServerStream::Helper> server_stream_helper_;
+ // Owned by the P2PQuicTransportImpl. |helper_| is placed before
+ // |connection_| to ensure it outlives it.
+ std::unique_ptr<net::QuicChromiumConnectionHelper> helper_;
+
+ std::unique_ptr<quic::QuicConnection> connection_;
+
+ std::unique_ptr<quic::QuicCryptoStream> crypto_stream_;
+ // Crypto information. Note that currently the handshake is insecure and these
+ // are not used...
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints_;
+
+ quic::Perspective perspective_;
+ // Outlives the P2PQuicTransport.
+ P2PQuicPacketTransport* packet_transport_;
+ P2PQuicTransport::Delegate* delegate_ = nullptr;
+ // Owned by whatever creates the P2PQuicTransportImpl. The |clock_| needs to
+ // outlive the P2PQuicTransportImpl.
+ quic::QuicClock* clock_ = nullptr;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
new file mode 100644
index 00000000000..c889ea9d2a2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc
@@ -0,0 +1,1177 @@
+// 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 "net/quic/quic_chromium_alarm_factory.h"
+#include "net/quic/test_task_runner.h"
+#include "net/test/gtest_util.h"
+#include "net/third_party/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quic/test_tools/mock_clock.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h"
+#include "third_party/webrtc/rtc_base/rtccertificate.h"
+#include "third_party/webrtc/rtc_base/sslfingerprint.h"
+#include "third_party/webrtc/rtc_base/sslidentity.h"
+
+namespace blink {
+
+namespace {
+
+// The types of callbacks that can be fired on a P2PQuicTransport::Delegate.
+enum class TransportCallbackType {
+ kNone,
+ kOnRemoteStopped,
+ kOnConnectionFailed,
+ kOnConnected,
+ kOnStream
+};
+
+// The types of callbacks that can be fired on a P2PQuicStream::Delegate.
+enum class StreamCallbackType { kNone, kOnRemoteReset, kOnRemoteFinish };
+
+// The QuicStreamDelegate implements counters for callbacks. It can also set
+// expectations for a specific callback. When an expectation is set the
+// quic::TestTaskRunner drives the test until the callbacks have been fired, and
+// we are no longer expecting the callback.
+class QuicStreamDelegateForTesting final : public P2PQuicStream::Delegate {
+ public:
+ ~QuicStreamDelegateForTesting() override {}
+
+ void OnRemoteReset() override {
+ if (callback_type_expected_ == StreamCallbackType::kOnRemoteReset) {
+ callback_type_expected_ = StreamCallbackType::kNone;
+ }
+ remote_reset_count_++;
+ };
+
+ void OnRemoteFinish() override {
+ if (callback_type_expected_ == StreamCallbackType::kOnRemoteFinish) {
+ callback_type_expected_ = StreamCallbackType::kNone;
+ }
+ remote_finish_count_++;
+ };
+
+ int remote_reset_count() { return remote_reset_count_; }
+
+ int remote_finish_count() { return remote_finish_count_; }
+
+ // Sets the type of callback expected to be called.
+ void ExpectCallback(StreamCallbackType callback_type) {
+ callback_type_expected_ = callback_type;
+ }
+
+ // Returns if we are expecting a callback that hasn't been fired yet.
+ bool IsExpectingCallback() const {
+ return callback_type_expected_ != StreamCallbackType::kNone;
+ }
+
+ private:
+ int remote_reset_count_ = 0;
+ int remote_finish_count_ = 0;
+ StreamCallbackType callback_type_expected_ = StreamCallbackType::kNone;
+};
+
+// Implements counters for callbacks. It can also set expectations for a
+// specific callback. When an expectation is set the quic::TestTaskRunner
+// drives the test until the callbacks have been fired, and we are no longer
+// expecting the callback.
+//
+// TODO(https://crbug.com/874296): If these files get moved to the platform
+// directory we will run the tests in a different test environment. In that case
+// it will make more sense to use the TestCompletionCallback and the RunLoop for
+// driving the test.
+class QuicTransportDelegateForTest final : public P2PQuicTransport::Delegate {
+ public:
+ ~QuicTransportDelegateForTest() override {}
+ void OnRemoteStopped() override {
+ if (callback_type_expected_ == TransportCallbackType::kOnRemoteStopped) {
+ callback_type_expected_ = TransportCallbackType::kNone;
+ }
+ stopped_count_++;
+ }
+
+ void OnConnectionFailed(const std::string& error_details,
+ bool from_remote) override {
+ if (callback_type_expected_ == TransportCallbackType::kOnConnectionFailed) {
+ callback_type_expected_ = TransportCallbackType::kNone;
+ }
+ connection_failed_count_++;
+ }
+
+ void OnConnected() override {
+ if (callback_type_expected_ == TransportCallbackType::kOnConnected) {
+ callback_type_expected_ = TransportCallbackType::kNone;
+ }
+ connected_count_++;
+ }
+
+ // We store the remotely created stream.
+ void OnStream(P2PQuicStream* stream) override {
+ if (callback_type_expected_ == TransportCallbackType::kOnStream) {
+ callback_type_expected_ = TransportCallbackType::kNone;
+ }
+ streams_.push_back(static_cast<P2PQuicStreamImpl*>(stream));
+ on_stream_count_++;
+ }
+
+ int stopped_count() const { return stopped_count_; }
+
+ int connection_failed_count() const { return connection_failed_count_; }
+
+ int connected_count() const { return connected_count_; }
+
+ int on_stream_count() const { return on_stream_count_; }
+
+ // Sets the type of callback expected to be called.
+ void ExpectCallback(TransportCallbackType callback_type) {
+ callback_type_expected_ = callback_type;
+ }
+
+ // Returns if we are expecting a callback that hasn't been fired yet.
+ bool IsExpectingCallback() const {
+ return callback_type_expected_ != TransportCallbackType::kNone;
+ }
+
+ std::vector<P2PQuicStreamImpl*> streams() const { return streams_; }
+
+ private:
+ TransportCallbackType callback_type_expected_ = TransportCallbackType::kNone;
+ int stopped_count_ = 0;
+ int connection_failed_count_ = 0;
+ int connected_count_ = 0;
+ int on_stream_count_ = 0;
+ // The delegates created for each stream as a result of the remote side
+ // creating streams and sending data (triggering OnStream). P2PQuicStreamsImpl
+ // are owned by the P2PQuicTransport.
+ std::vector<P2PQuicStreamImpl*> streams_;
+};
+
+// This is a fake packet transport to be used by the P2PQuicTransportImpl. It
+// allows to easily connect two packet transports together. We send packets
+// asynchronously, by using the same alarm factory that is being used for the
+// underlying QUIC library.
+class FakePacketTransport : public P2PQuicPacketTransport,
+ public quic::QuicAlarm::Delegate {
+ public:
+ FakePacketTransport(quic::QuicAlarmFactory* alarm_factory,
+ quic::MockClock* clock)
+ : alarm_(alarm_factory->CreateAlarm(new AlarmDelegate(this))),
+ clock_(clock) {}
+ ~FakePacketTransport() override {
+ // The write observer should be unset when it is destroyed.
+ DCHECK(!write_observer_);
+ };
+
+ // Called by QUIC for writing data to the other side. The flow for writing a
+ // packet is P2PQuicTransportImpl --> quic::QuicConnection -->
+ // quic::QuicPacketWriter --> FakePacketTransport. In this case the
+ // FakePacketTransport just writes directly to the FakePacketTransport on the
+ // other side.
+ int WritePacket(const QuicPacket& packet) override {
+ // For the test there should always be a peer_packet_transport_ connected at
+ // this point.
+ if (!peer_packet_transport_) {
+ return 0;
+ }
+ last_packet_num_ = packet.packet_number;
+ packet_queue_.emplace_back(packet.buffer, packet.buf_len);
+ alarm_->Cancel();
+ // We don't want get 0 RTT.
+ alarm_->Set(clock_->Now() + quic::QuicTime::Delta::FromMicroseconds(10));
+
+ return packet.buf_len;
+ }
+
+ // Sets the P2PQuicTransportImpl as the delegate.
+ void SetReceiveDelegate(
+ P2PQuicPacketTransport::ReceiveDelegate* delegate) override {
+ // We can't set two ReceiveDelegates for one packet transport.
+ DCHECK(!delegate_ || !delegate);
+ delegate_ = delegate;
+ }
+
+ void SetWriteObserver(
+ P2PQuicPacketTransport::WriteObserver* write_observer) override {
+ // We can't set two WriteObservers for one packet transport.
+ DCHECK(!write_observer_ || !write_observer);
+ write_observer_ = write_observer;
+ }
+
+ bool Writable() override { return true; }
+
+ // Connects the other FakePacketTransport, so we can write to the peer.
+ void ConnectPeerTransport(FakePacketTransport* peer_packet_transport) {
+ DCHECK(!peer_packet_transport_);
+ peer_packet_transport_ = peer_packet_transport;
+ }
+
+ // Disconnects the delegate, so we no longer write to it. The test must call
+ // this before destructing either of the packet transports!
+ void DisconnectPeerTransport(FakePacketTransport* peer_packet_transport) {
+ DCHECK(peer_packet_transport_ == peer_packet_transport);
+ peer_packet_transport_ = nullptr;
+ }
+
+ // The callback used in order for us to communicate between
+ // FakePacketTransports.
+ void OnDataReceivedFromPeer(const char* data, size_t data_len) {
+ DCHECK(delegate_);
+ delegate_->OnPacketDataReceived(data, data_len);
+ }
+
+ int last_packet_num() { return last_packet_num_; }
+
+ private:
+ // Wraps the FakePacketTransport so that we can pass in a raw pointer that can
+ // be reference counted when calling CreateAlarm().
+ class AlarmDelegate : public quic::QuicAlarm::Delegate {
+ public:
+ explicit AlarmDelegate(FakePacketTransport* packet_transport)
+ : packet_transport_(packet_transport) {}
+
+ void OnAlarm() override { packet_transport_->OnAlarm(); }
+
+ private:
+ FakePacketTransport* packet_transport_;
+ };
+
+ // Called when we should write any buffered data.
+ void OnAlarm() override {
+ // Send the data to the peer at this point.
+ peer_packet_transport_->OnDataReceivedFromPeer(
+ packet_queue_.front().c_str(), packet_queue_.front().length());
+ packet_queue_.pop_front();
+
+ // If there's more packets to be sent out, reset the alarm to send it as the
+ // next task.
+ if (!packet_queue_.empty()) {
+ alarm_->Cancel();
+ alarm_->Set(clock_->Now());
+ }
+ }
+ // If async, packets are queued here to send.
+ quic::QuicDeque<quic::QuicString> packet_queue_;
+ // Alarm used to send data asynchronously.
+ quic::QuicArenaScopedPtr<quic::QuicAlarm> alarm_;
+ // The P2PQuicTransportImpl, which sets itself as the delegate in its
+ // constructor. After receiving data it forwards it along to QUIC.
+ P2PQuicPacketTransport::ReceiveDelegate* delegate_ = nullptr;
+
+ // The P2PQuicPacketWriter, which sets itself as a write observer
+ // during the P2PQuicTransportFactoryImpl::CreateQuicTransport. It is
+ // owned by the QuicConnection and will
+ P2PQuicPacketTransport::WriteObserver* write_observer_ = nullptr;
+
+ // The other FakePacketTransport that we are writing to. It's the
+ // responsibility of the test to disconnect this delegate
+ // (set_delegate(nullptr);) before it is destructed.
+ FakePacketTransport* peer_packet_transport_ = nullptr;
+ quic::QuicPacketNumber last_packet_num_;
+ quic::MockClock* clock_;
+};
+
+// A helper class to bundle test objects together.
+class QuicPeerForTest {
+ public:
+ QuicPeerForTest(
+ std::unique_ptr<FakePacketTransport> packet_transport,
+ std::unique_ptr<QuicTransportDelegateForTest> quic_transport_delegate,
+ std::unique_ptr<P2PQuicTransportImpl> quic_transport,
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate)
+ : packet_transport_(std::move(packet_transport)),
+ quic_transport_delegate_(std::move(quic_transport_delegate)),
+ quic_transport_(std::move(quic_transport)),
+ certificate_(certificate) {}
+
+ FakePacketTransport* packet_transport() { return packet_transport_.get(); }
+
+ QuicTransportDelegateForTest* quic_transport_delegate() {
+ return quic_transport_delegate_.get();
+ }
+
+ P2PQuicTransportImpl* quic_transport() { return quic_transport_.get(); }
+
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate() { return certificate_; }
+
+ private:
+ std::unique_ptr<FakePacketTransport> packet_transport_;
+ std::unique_ptr<QuicTransportDelegateForTest> quic_transport_delegate_;
+ std::unique_ptr<P2PQuicTransportImpl> quic_transport_;
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
+};
+
+rtc::scoped_refptr<rtc::RTCCertificate> CreateTestCertificate() {
+ rtc::KeyParams params;
+ rtc::SSLIdentity* ssl_identity =
+ rtc::SSLIdentity::Generate("dummy_certificate", params);
+ return rtc::RTCCertificate::Create(
+ std::unique_ptr<rtc::SSLIdentity>(ssl_identity));
+}
+
+// Allows faking a failing handshake.
+class FailingProofVerifier : public quic::ProofVerifier {
+ public:
+ FailingProofVerifier() {}
+ ~FailingProofVerifier() override {}
+
+ // ProofVerifier override.
+ quic::QuicAsyncStatus VerifyProof(
+ const quic::QuicString& hostname,
+ const uint16_t port,
+ const quic::QuicString& server_config,
+ quic::QuicTransportVersion transport_version,
+ quic::QuicStringPiece chlo_hash,
+ const std::vector<quic::QuicString>& certs,
+ const quic::QuicString& cert_sct,
+ const quic::QuicString& signature,
+ const quic::ProofVerifyContext* context,
+ quic::QuicString* error_details,
+ std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
+ std::unique_ptr<quic::ProofVerifierCallback> callback) override {
+ return quic::QUIC_FAILURE;
+ }
+
+ quic::QuicAsyncStatus VerifyCertChain(
+ const quic::QuicString& hostname,
+ const std::vector<quic::QuicString>& certs,
+ const quic::ProofVerifyContext* context,
+ quic::QuicString* error_details,
+ std::unique_ptr<quic::ProofVerifyDetails>* details,
+ std::unique_ptr<quic::ProofVerifierCallback> callback) override {
+ return quic::QUIC_FAILURE;
+ }
+
+ std::unique_ptr<quic::ProofVerifyContext> CreateDefaultContext() override {
+ return nullptr;
+ }
+};
+} // namespace
+
+// Unit tests for the P2PQuicTransport, using an underlying fake packet
+// transport that sends packets directly between endpoints. This also tests
+// P2PQuicStreams for test cases that involve two streams connected between
+// separate endpoints. This is because the P2PQuicStream is highly coupled to
+// the P2PQuicSession for communicating between endpoints, so we would like to
+// test it with the real session object.
+//
+// The test is driven using the quic::TestTaskRunner to run posted tasks until
+// callbacks have been fired.
+class P2PQuicTransportTest : public testing::Test {
+ public:
+ P2PQuicTransportTest() {}
+
+ ~P2PQuicTransportTest() override {
+ // This must be done before desctructing the transports so that we don't
+ // have any dangling pointers.
+ client_peer_->packet_transport()->DisconnectPeerTransport(
+ server_peer_->packet_transport());
+ server_peer_->packet_transport()->DisconnectPeerTransport(
+ client_peer_->packet_transport());
+ }
+
+ // Connects both peer's underlying transports and creates both
+ // P2PQuicTransportImpls.
+ void Initialize(bool can_respond_to_crypto_handshake = true) {
+ // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
+ clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(1000));
+ runner_ = new net::test::TestTaskRunner(&clock_);
+ net::QuicChromiumAlarmFactory* alarm_factory =
+ new net::QuicChromiumAlarmFactory(runner_.get(), &clock_);
+ quic_transport_factory_ = std::make_unique<P2PQuicTransportFactoryImpl>(
+ &clock_, std::unique_ptr<net::QuicChromiumAlarmFactory>(alarm_factory));
+
+ std::unique_ptr<FakePacketTransport> client_packet_transport =
+ std::make_unique<FakePacketTransport>(alarm_factory, &clock_);
+ std::unique_ptr<FakePacketTransport> server_packet_transport =
+ std::make_unique<FakePacketTransport>(alarm_factory, &clock_);
+ // Connect the transports so that they can speak to each other.
+ client_packet_transport->ConnectPeerTransport(
+ server_packet_transport.get());
+ server_packet_transport->ConnectPeerTransport(
+ client_packet_transport.get());
+ rtc::scoped_refptr<rtc::RTCCertificate> client_cert =
+ CreateTestCertificate();
+
+ std::unique_ptr<QuicTransportDelegateForTest>
+ client_quic_transport_delegate =
+ std::make_unique<QuicTransportDelegateForTest>();
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> client_certificates;
+ client_certificates.push_back(client_cert);
+ P2PQuicTransportConfig client_config(client_quic_transport_delegate.get(),
+ client_packet_transport.get(),
+ client_certificates);
+ client_config.is_server = false;
+ client_config.can_respond_to_crypto_handshake =
+ can_respond_to_crypto_handshake;
+ // We can't downcast a unique_ptr to an object, so we have to release, cast
+ // it, then create a unique_ptr of the downcasted pointer.
+ P2PQuicTransportImpl* client_quic_transport_ptr =
+ static_cast<P2PQuicTransportImpl*>(
+ quic_transport_factory_
+ ->CreateQuicTransport(std::move(client_config))
+ .release());
+ std::unique_ptr<P2PQuicTransportImpl> client_quic_transport =
+ std::unique_ptr<P2PQuicTransportImpl>(client_quic_transport_ptr);
+ client_peer_ = std::make_unique<QuicPeerForTest>(
+ std::move(client_packet_transport),
+ std::move(client_quic_transport_delegate),
+ std::move(client_quic_transport), client_cert);
+
+ std::unique_ptr<QuicTransportDelegateForTest>
+ server_quic_transport_delegate =
+ std::make_unique<QuicTransportDelegateForTest>();
+
+ rtc::scoped_refptr<rtc::RTCCertificate> server_cert =
+ CreateTestCertificate();
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> server_certificates;
+ server_certificates.push_back(server_cert);
+ P2PQuicTransportConfig server_config(server_quic_transport_delegate.get(),
+ server_packet_transport.get(),
+ server_certificates);
+ server_config.is_server = true;
+ server_config.can_respond_to_crypto_handshake =
+ can_respond_to_crypto_handshake;
+ P2PQuicTransportImpl* server_quic_transport_ptr =
+ static_cast<P2PQuicTransportImpl*>(
+ quic_transport_factory_
+ ->CreateQuicTransport(std::move(server_config))
+ .release());
+ std::unique_ptr<P2PQuicTransportImpl> server_quic_transport =
+ std::unique_ptr<P2PQuicTransportImpl>(server_quic_transport_ptr);
+ server_peer_ = std::make_unique<QuicPeerForTest>(
+ std::move(server_packet_transport),
+ std::move(server_quic_transport_delegate),
+ std::move(server_quic_transport), server_cert);
+ }
+
+ // Sets a FailingProofVerifier to the client transport before initializing
+ // the its crypto stream. This allows the client to fail the proof
+ // verification step during the crypto handshake.
+ void InitializeWithFailingProofVerification() {
+ // Allows us to initialize the crypto streams after constructing the
+ // objects.
+ Initialize(false);
+ // Create the client crypto config and insert it into the client transport.
+ std::unique_ptr<quic::ProofVerifier> proof_verifier(
+ new FailingProofVerifier);
+ std::unique_ptr<quic::QuicCryptoClientConfig> crypto_client_config =
+ std::make_unique<quic::QuicCryptoClientConfig>(
+ std::move(proof_verifier),
+ quic::TlsClientHandshaker::CreateSslCtx());
+ client_peer_->quic_transport()->set_crypto_client_config(
+ std::move(crypto_client_config));
+ // Now initialize the crypto streams.
+ client_peer_->quic_transport()->InitializeCryptoStream();
+ server_peer_->quic_transport()->InitializeCryptoStream();
+ }
+
+ // Drives the test until we are't expecting any more callbacks to be fired.
+ // This is done using the net::test::TestTaskRunner, which runs the tasks
+ // in the correct order and then advances the quic::MockClock to the time the
+ // task is run.
+ void RunUntilCallbacksFired() {
+ while (server_peer_->quic_transport_delegate()->IsExpectingCallback() ||
+ client_peer_->quic_transport_delegate()->IsExpectingCallback() ||
+ ExpectingStreamCallback()) {
+ // We shouldn't enter a case where we are expecting a callback
+ // and we're out of tasks to run.
+ ASSERT_GT(runner_->GetPostedTasks().size(), 0u);
+ runner_->RunNextTask();
+ }
+ }
+
+ bool ExpectingStreamCallback() {
+ return streams_setup_ && (client_stream_delegate_->IsExpectingCallback() ||
+ server_stream_delegate_->IsExpectingCallback());
+ }
+
+ // Drives the test by running the current tasks that are posted.
+ void RunCurrentTasks() {
+ size_t posted_tasks_size = runner_->GetPostedTasks().size();
+ for (size_t i = 0; i < posted_tasks_size; ++i) {
+ runner_->RunNextTask();
+ }
+ }
+
+ // Starts the handshake, by setting the remote fingerprints and kicking off
+ // the handshake from the client.
+ void StartHandshake() {
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> server_fingerprints;
+ server_fingerprints.emplace_back(rtc::SSLFingerprint::Create(
+ "sha-256", server_peer_->certificate()->identity()));
+ // The server side doesn't currently need call this to set the remote
+ // fingerprints, but once P2P certificate verification is supported in the
+ // TLS 1.3 handshake this will ben necessary.
+ server_peer_->quic_transport()->Start(std::move(server_fingerprints));
+
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> client_fingerprints;
+ client_fingerprints.emplace_back(rtc::SSLFingerprint::Create(
+ "sha-256", client_peer_->certificate()->identity()));
+ client_peer_->quic_transport()->Start(std::move(client_fingerprints));
+ }
+
+ // Sets up an initial handshake and connection between peers.
+ void Connect() {
+ client_peer_->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnected);
+ server_peer_->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnected);
+ StartHandshake();
+ RunUntilCallbacksFired();
+ ExpectSecureConnection();
+ }
+
+ // Creates a P2PQuicStreamImpl on both the client and server side that are
+ // connected to each other.
+ void SetupConnectedStreams() {
+ // We must already have a secure connection before streams are created.
+ ASSERT_TRUE(client_peer_->quic_transport()->IsEncryptionEstablished());
+ ASSERT_TRUE(server_peer_->quic_transport()->IsEncryptionEstablished());
+
+ client_stream_ = client_peer_->quic_transport()->CreateStream();
+ ASSERT_TRUE(client_stream_);
+ client_stream_id_ = client_stream_->id();
+ client_stream_delegate_ = std::make_unique<QuicStreamDelegateForTesting>();
+ client_stream_->SetDelegate(client_stream_delegate_.get());
+
+ // Send some data to trigger the remote side (server side) to get an
+ // incoming stream.
+ server_peer_->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnStream);
+ client_stream_->WriteOrBufferData("hello", false, nullptr);
+ RunUntilCallbacksFired();
+
+ ASSERT_EQ(1u, server_peer_->quic_transport()->GetNumActiveStreams());
+ ASSERT_EQ(1u, client_peer_->quic_transport()->GetNumActiveStreams());
+ ASSERT_EQ(1u, server_peer_->quic_transport_delegate()->streams().size());
+ server_stream_ = server_peer_->quic_transport_delegate()->streams()[0];
+ ASSERT_TRUE(server_stream_);
+ server_stream_id_ = server_stream_->id();
+ server_stream_delegate_ = std::make_unique<QuicStreamDelegateForTesting>();
+ server_stream_->SetDelegate(server_stream_delegate_.get());
+ streams_setup_ = true;
+ }
+
+ void ExpectSecureConnection() {
+ EXPECT_TRUE(client_peer_->quic_transport()->IsEncryptionEstablished());
+ EXPECT_TRUE(client_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_TRUE(server_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_TRUE(server_peer_->quic_transport()->IsEncryptionEstablished());
+ }
+
+ void ExpectConnectionNotEstablished() {
+ EXPECT_FALSE(client_peer_->quic_transport()->IsEncryptionEstablished());
+ EXPECT_FALSE(client_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_FALSE(server_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_FALSE(server_peer_->quic_transport()->IsEncryptionEstablished());
+ }
+
+ // Test that the callbacks were called appropriately after a successful
+ // crypto handshake.
+ void ExpectSuccessfulHandshake() {
+ EXPECT_EQ(1, client_peer_->quic_transport_delegate()->connected_count());
+ EXPECT_EQ(0, client_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, client_peer_->quic_transport_delegate()->connection_failed_count());
+
+ EXPECT_EQ(1, server_peer_->quic_transport_delegate()->connected_count());
+ EXPECT_EQ(0, server_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, server_peer_->quic_transport_delegate()->connection_failed_count());
+ }
+
+ void ExpectTransportsClosed() {
+ EXPECT_TRUE(client_peer_->quic_transport()->IsClosed());
+ EXPECT_TRUE(server_peer_->quic_transport()->IsClosed());
+ }
+
+ void ExpectStreamsClosed() {
+ ASSERT_TRUE(streams_setup_);
+ EXPECT_EQ(0u, client_peer_->quic_transport()->GetNumActiveStreams());
+ EXPECT_TRUE(
+ client_peer_->quic_transport()->IsClosedStream(client_stream_id_));
+ EXPECT_EQ(0u, server_peer_->quic_transport()->GetNumActiveStreams());
+ EXPECT_TRUE(
+ server_peer()->quic_transport()->IsClosedStream(server_stream_id_));
+ }
+
+ // Exposes these private functions to the test.
+ bool IsClientClosed() { return client_peer_->quic_transport()->IsClosed(); }
+ bool IsServerClosed() { return server_peer_->quic_transport()->IsClosed(); }
+
+ // Tests that the callbacks were appropriately called after the client
+ // stops the connection. Only the server should receive the OnRemoteStopped()
+ // callback.
+ void ExpectClientStopped() {
+ ExpectTransportsClosed();
+ EXPECT_EQ(0, client_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, client_peer_->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(1, server_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, server_peer_->quic_transport_delegate()->connection_failed_count());
+ }
+
+ // Tests that the callbacks were appropriately called after the server
+ // stops the connection. Only the client should receive the OnRemoteStopped()
+ // callback.
+ void ExpectServerStopped() {
+ ExpectTransportsClosed();
+ EXPECT_EQ(1, client_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, client_peer_->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(0, server_peer_->quic_transport_delegate()->stopped_count());
+ EXPECT_EQ(
+ 0, server_peer_->quic_transport_delegate()->connection_failed_count());
+ }
+
+ QuicPeerForTest* client_peer() { return client_peer_.get(); }
+
+ quic::QuicConnection* client_connection() {
+ return client_peer_->quic_transport()->connection();
+ }
+
+ QuicPeerForTest* server_peer() { return server_peer_.get(); }
+
+ quic::QuicConnection* server_connection() {
+ return server_peer_->quic_transport()->connection();
+ }
+
+ P2PQuicStreamImpl* server_stream() { return server_stream_; }
+
+ P2PQuicStreamImpl* client_stream() { return client_stream_; }
+
+ quic::QuicStreamId server_stream_id() { return server_stream_id_; }
+
+ quic::QuicStreamId client_stream_id() { return client_stream_id_; }
+
+ QuicStreamDelegateForTesting* server_stream_delegate() {
+ return server_stream_delegate_.get();
+ }
+
+ QuicStreamDelegateForTesting* client_stream_delegate() {
+ return client_stream_delegate_.get();
+ }
+
+ private:
+ quic::MockClock clock_;
+ // The TestTaskRunner is used by the QUIC library for setting/firing alarms.
+ // We are able to explicitly run these tasks ourselves with the
+ // TestTaskRunner.
+ scoped_refptr<net::test::TestTaskRunner> runner_;
+
+ std::unique_ptr<P2PQuicTransportFactoryImpl> quic_transport_factory_;
+ std::unique_ptr<QuicPeerForTest> client_peer_;
+ std::unique_ptr<QuicPeerForTest> server_peer_;
+
+ // Stream objects, which are created with SetupConnectedStream().
+ bool streams_setup_ = false;
+ std::unique_ptr<QuicStreamDelegateForTesting> client_stream_delegate_;
+ std::unique_ptr<QuicStreamDelegateForTesting> server_stream_delegate_;
+ // The P2PQuicStreamImpls are owned by the P2PQuicTransport.
+ P2PQuicStreamImpl* client_stream_ = nullptr;
+ P2PQuicStreamImpl* server_stream_ = nullptr;
+ // We cache the values before the streams are potentially closed and deleted.
+ quic::QuicStreamId server_stream_id_;
+ quic::QuicStreamId client_stream_id_;
+};
+
+// Tests that we can connect two quic transports.
+TEST_F(P2PQuicTransportTest, HandshakeConnectsPeers) {
+ Initialize();
+ Connect();
+
+ ExpectSuccessfulHandshake();
+}
+
+// Tests the standard case for the server side closing the connection.
+TEST_F(P2PQuicTransportTest, ServerStops) {
+ Initialize();
+ Connect();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnRemoteStopped);
+ server_peer()->quic_transport()->Stop();
+ RunUntilCallbacksFired();
+
+ ExpectServerStopped();
+}
+
+// Tests the standard case for the client side closing the connection.
+TEST_F(P2PQuicTransportTest, ClientStops) {
+ Initialize();
+ Connect();
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnRemoteStopped);
+ client_peer()->quic_transport()->Stop();
+ RunUntilCallbacksFired();
+
+ ExpectClientStopped();
+}
+
+// Tests that if either side tries to close the connection a second time, it
+// will be ignored because the connection has already been closed.
+TEST_F(P2PQuicTransportTest, StopAfterStopped) {
+ Initialize();
+ Connect();
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnRemoteStopped);
+ client_peer()->quic_transport()->Stop();
+ RunUntilCallbacksFired();
+ client_peer()->quic_transport()->Stop();
+ server_peer()->quic_transport()->Stop();
+ RunCurrentTasks();
+
+ ExpectClientStopped();
+}
+
+// Tests that when the client closes the connection the subsequent call to
+// Start() will be ignored.
+TEST_F(P2PQuicTransportTest, ClientStopsBeforeClientStarts) {
+ Initialize();
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnRemoteStopped);
+ client_peer()->quic_transport()->Stop();
+ StartHandshake();
+ RunUntilCallbacksFired();
+
+ ExpectConnectionNotEstablished();
+ ExpectClientStopped();
+}
+
+// Tests that if the server closes the connection before the client starts the
+// handshake, the client side will already be closed and Start() will be
+// ignored.
+TEST_F(P2PQuicTransportTest, ServerStopsBeforeClientStarts) {
+ Initialize();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnRemoteStopped);
+ server_peer()->quic_transport()->Stop();
+ StartHandshake();
+ RunUntilCallbacksFired();
+
+ ExpectConnectionNotEstablished();
+ ExpectServerStopped();
+}
+
+// Tests that when the server's connection fails and then a handshake is
+// attempted the transports will not become connected.
+TEST_F(P2PQuicTransportTest, ClientConnectionClosesBeforeHandshake) {
+ Initialize();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ client_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ StartHandshake();
+ RunUntilCallbacksFired();
+
+ ExpectConnectionNotEstablished();
+}
+
+// Tests that when the server's connection fails and then a handshake is
+// attempted the transports will not become connected.
+TEST_F(P2PQuicTransportTest, ServerConnectionClosesBeforeHandshake) {
+ Initialize();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ StartHandshake();
+ RunUntilCallbacksFired();
+
+ ExpectConnectionNotEstablished();
+}
+
+// Tests that the appropriate callbacks are fired when the handshake fails.
+TEST_F(P2PQuicTransportTest, HandshakeFailure) {
+ InitializeWithFailingProofVerification();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ StartHandshake();
+ RunUntilCallbacksFired();
+
+ EXPECT_EQ(
+ 1, client_peer()->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(
+ 1, server_peer()->quic_transport_delegate()->connection_failed_count());
+ ExpectConnectionNotEstablished();
+ ExpectTransportsClosed();
+}
+
+// Tests that the appropriate callbacks are fired when the client's connection
+// fails after the transports have connected.
+TEST_F(P2PQuicTransportTest, ClientConnectionFailureAfterConnected) {
+ Initialize();
+ Connect();
+ // Close the connection with an internal QUIC error.
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ client_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ RunUntilCallbacksFired();
+
+ ExpectTransportsClosed();
+ EXPECT_EQ(
+ 1, client_peer()->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(
+ 1, server_peer()->quic_transport_delegate()->connection_failed_count());
+}
+
+// Tests that the appropriate callbacks are fired when the server's connection
+// fails after the transports have connected.
+TEST_F(P2PQuicTransportTest, ServerConnectionFailureAfterConnected) {
+ Initialize();
+ Connect();
+ // Close the connection with an internal QUIC error.
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ RunUntilCallbacksFired();
+
+ ExpectTransportsClosed();
+ EXPECT_EQ(
+ 1, client_peer()->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(
+ 1, server_peer()->quic_transport_delegate()->connection_failed_count());
+}
+
+// Tests that closing the connection with no ACK frame does not make any
+// difference in the closing procedure.
+TEST_F(P2PQuicTransportTest, ConnectionFailureNoAckFrame) {
+ Initialize();
+ Connect();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ client_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET_WITH_NO_ACK);
+ RunUntilCallbacksFired();
+
+ ExpectTransportsClosed();
+ EXPECT_EQ(
+ 1, client_peer()->quic_transport_delegate()->connection_failed_count());
+ EXPECT_EQ(
+ 1, server_peer()->quic_transport_delegate()->connection_failed_count());
+}
+
+// Tests that a silent failure will only close on one side.
+TEST_F(P2PQuicTransportTest, ConnectionSilentFailure) {
+ Initialize();
+ Connect();
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnConnectionFailed);
+ client_connection()->CloseConnection(
+ quic::QuicErrorCode::QUIC_INTERNAL_ERROR, "internal error",
+ quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ RunUntilCallbacksFired();
+
+ EXPECT_TRUE(IsClientClosed());
+ EXPECT_EQ(
+ 1, client_peer()->quic_transport_delegate()->connection_failed_count());
+ EXPECT_FALSE(IsServerClosed());
+ EXPECT_EQ(
+ 0, server_peer()->quic_transport_delegate()->connection_failed_count());
+}
+
+// Tests that the client transport can create a stream and an incoming stream
+// will be created on the remote server.
+TEST_F(P2PQuicTransportTest, ClientCreatesStream) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* client_stream =
+ client_peer()->quic_transport()->CreateStream();
+ RunCurrentTasks();
+
+ ASSERT_TRUE(client_stream);
+ EXPECT_TRUE(client_peer()->quic_transport()->HasOpenDynamicStreams());
+ EXPECT_EQ(0, server_peer()->quic_transport_delegate()->on_stream_count());
+ EXPECT_FALSE(server_peer()->quic_transport()->HasOpenDynamicStreams());
+
+ // After sending data across it will trigger a stream to be created on the
+ // server side.
+ server_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnStream);
+ client_stream->WriteOrBufferData("hello", false, nullptr);
+ RunUntilCallbacksFired();
+
+ EXPECT_EQ(1, server_peer()->quic_transport_delegate()->on_stream_count());
+ EXPECT_TRUE(server_peer()->quic_transport()->HasOpenDynamicStreams());
+}
+
+// Tests that the server transport can create a stream and an incoming stream
+// will be created on the remote client.
+TEST_F(P2PQuicTransportTest, ServerCreatesStream) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* server_stream =
+ server_peer()->quic_transport()->CreateStream();
+ RunCurrentTasks();
+
+ ASSERT_TRUE(server_stream);
+ EXPECT_TRUE(server_peer()->quic_transport()->HasOpenDynamicStreams());
+ EXPECT_EQ(0, client_peer()->quic_transport_delegate()->on_stream_count());
+ EXPECT_FALSE(client_peer()->quic_transport()->HasOpenDynamicStreams());
+
+ // After sending data across it will trigger a stream to be created on the
+ // client side.
+ client_peer()->quic_transport_delegate()->ExpectCallback(
+ TransportCallbackType::kOnStream);
+ server_stream->WriteOrBufferData("hello", false, nullptr);
+ RunUntilCallbacksFired();
+
+ EXPECT_EQ(1, client_peer()->quic_transport_delegate()->on_stream_count());
+ EXPECT_TRUE(client_peer()->quic_transport()->HasOpenDynamicStreams());
+}
+
+// Tests that when the client transport calls Stop() it closes its outgoing
+// stream, which, in turn closes the incoming stream on the server quic
+// transport.
+TEST_F(P2PQuicTransportTest, ClientClosingConnectionClosesStreams) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ client_peer()->quic_transport()->Stop();
+ RunCurrentTasks();
+
+ ExpectTransportsClosed();
+ ExpectStreamsClosed();
+}
+
+// Tests that when the server transport calls Stop() it closes its incoming
+// stream, which, in turn closes the outgoing stream on the client quic
+// transport.
+TEST_F(P2PQuicTransportTest, ServerClosingConnectionClosesStreams) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ server_peer()->quic_transport()->Stop();
+ RunCurrentTasks();
+
+ ExpectTransportsClosed();
+ ExpectStreamsClosed();
+}
+
+// Tests that calling Reset() will close both side's streams for reading and
+// writing.
+TEST_F(P2PQuicTransportTest, ClientStreamReset) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ server_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteReset);
+ client_stream()->Reset();
+ RunUntilCallbacksFired();
+
+ ExpectStreamsClosed();
+}
+
+// Tests that calling Reset() will close both side's streams for reading and
+// writing.
+TEST_F(P2PQuicTransportTest, ServerStreamReset) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ client_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteReset);
+ server_stream()->Reset();
+ RunUntilCallbacksFired();
+
+ ExpectStreamsClosed();
+}
+
+// Tests the basic case for calling Finish() on both sides.
+TEST_F(P2PQuicTransportTest, StreamFinishHandshake) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ server_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteFinish);
+ client_stream()->Finish();
+ RunUntilCallbacksFired();
+
+ ASSERT_EQ(1u, server_peer()->quic_transport()->GetNumActiveStreams());
+ ASSERT_EQ(1u, client_peer()->quic_transport()->GetNumActiveStreams());
+ EXPECT_EQ(0, client_stream_delegate()->remote_finish_count());
+ EXPECT_TRUE(client_stream()->write_side_closed());
+ EXPECT_FALSE(client_stream()->reading_stopped());
+ EXPECT_FALSE(server_stream()->write_side_closed());
+ EXPECT_TRUE(server_stream()->reading_stopped());
+ EXPECT_FALSE(
+ server_peer()->quic_transport()->IsClosedStream(server_stream_id()));
+ EXPECT_FALSE(
+ client_peer()->quic_transport()->IsClosedStream(client_stream_id()));
+
+ client_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteFinish);
+ server_stream()->Finish();
+ RunUntilCallbacksFired();
+ // This is required so that the client acks the FIN back to the server side
+ // and the server side removes its zombie streams.
+ RunCurrentTasks();
+
+ ASSERT_EQ(0u, server_peer()->quic_transport()->GetNumActiveStreams());
+ ASSERT_EQ(0u, client_peer()->quic_transport()->GetNumActiveStreams());
+ EXPECT_EQ(1, server_stream_delegate()->remote_finish_count());
+ EXPECT_EQ(1, client_stream_delegate()->remote_finish_count());
+ EXPECT_TRUE(
+ server_peer()->quic_transport()->IsClosedStream(server_stream_id()));
+ EXPECT_TRUE(
+ client_peer()->quic_transport()->IsClosedStream(client_stream_id()));
+}
+
+// Tests that if a Reset() is called after Finish(), both sides close down
+// properly.
+TEST_F(P2PQuicTransportTest, StreamResetAfterFinish) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ server_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteFinish);
+ client_stream()->Finish();
+ RunUntilCallbacksFired();
+
+ server_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteReset);
+ client_stream()->Reset();
+ RunUntilCallbacksFired();
+
+ ExpectStreamsClosed();
+ EXPECT_EQ(0, client_stream_delegate()->remote_reset_count());
+}
+
+// Tests that if a Reset() is called after receiving a stream frame with the FIN
+// bit set from the remote side, both sides close down properly.
+TEST_F(P2PQuicTransportTest, StreamResetAfterRemoteFinish) {
+ Initialize();
+ Connect();
+ SetupConnectedStreams();
+
+ server_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteFinish);
+ client_stream()->Finish();
+ RunUntilCallbacksFired();
+
+ client_stream_delegate()->ExpectCallback(StreamCallbackType::kOnRemoteReset);
+ // The server stream has received its FIN bit from the remote side, and
+ // responds with a Reset() to close everything down.
+ server_stream()->Reset();
+ RunUntilCallbacksFired();
+
+ ExpectStreamsClosed();
+ EXPECT_EQ(0, server_stream_delegate()->remote_reset_count());
+}
+
+// The following unit tests are more isolated to the P2PQuicStreamImpl
+// implementation. They only test a stream's behavior on one side (not any
+// interactions between two connected streams).
+
+TEST_F(P2PQuicTransportTest, StreamFinishSendsFinAndCanNoLongerWrite) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+
+ stream->Finish();
+ EXPECT_TRUE(stream->fin_sent());
+ EXPECT_TRUE(stream->write_side_closed());
+ EXPECT_FALSE(stream->reading_stopped());
+}
+
+TEST_F(P2PQuicTransportTest, StreamResetSendsRstAndBecomesClosed) {
+ Initialize();
+ Connect();
+
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+ quic::QuicStreamId stream_id = stream->id();
+
+ stream->Reset();
+
+ EXPECT_TRUE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+}
+
+// Tests that when a stream receives a stream frame with the FIN bit set it
+// will fire the appropriate callback and close the stream for reading.
+TEST_F(P2PQuicTransportTest, StreamOnStreamFrameWithFin) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+ QuicStreamDelegateForTesting stream_delegate;
+ stream->SetDelegate(&stream_delegate);
+
+ quic::QuicStreamFrame fin_frame(stream->id(), /*fin=*/true, 0, 0);
+ stream->OnStreamFrame(fin_frame);
+ EXPECT_EQ(1, stream_delegate.remote_finish_count());
+ EXPECT_TRUE(stream->reading_stopped());
+ EXPECT_FALSE(stream->write_side_closed());
+}
+
+// Tests that when a stream receives a stream frame with the FIN bit set after
+// it has called Finish(), then the stream will close.
+TEST_F(P2PQuicTransportTest, StreamClosedAfterReceivesFin) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+ quic::QuicStreamId stream_id = stream->id();
+ QuicStreamDelegateForTesting stream_delegate;
+ stream->SetDelegate(&stream_delegate);
+
+ stream->Finish();
+ EXPECT_FALSE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+ quic::QuicStreamFrame fin_frame(stream->id(), /*fin=*/true, 0, 0);
+ stream->OnStreamFrame(fin_frame);
+
+ EXPECT_TRUE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+}
+
+// Tests that when a stream calls Finish() after receiving a stream frame with
+// the FIN bit then the stream will close.
+TEST_F(P2PQuicTransportTest, StreamClosedAfterFinish) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+ quic::QuicStreamId stream_id = stream->id();
+ QuicStreamDelegateForTesting stream_delegate;
+ stream->SetDelegate(&stream_delegate);
+
+ quic::QuicStreamFrame fin_frame(stream->id(), /*fin=*/true, 0, 0);
+ stream->OnStreamFrame(fin_frame);
+ EXPECT_FALSE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+ stream->Finish();
+
+ EXPECT_TRUE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+}
+
+// Tests that when a stream receives a RST_STREAM frame it will fire the
+// appropriate callback and the stream will become closed.
+TEST_F(P2PQuicTransportTest, StreamClosedAfterReceivingReset) {
+ Initialize();
+ Connect();
+ P2PQuicStreamImpl* stream = client_peer()->quic_transport()->CreateStream();
+ quic::QuicStreamId stream_id = stream->id();
+ QuicStreamDelegateForTesting stream_delegate;
+ stream->SetDelegate(&stream_delegate);
+
+ quic::QuicRstStreamFrame rst_frame(quic::kInvalidControlFrameId, stream_id,
+ quic::QUIC_STREAM_CANCELLED, 0);
+ stream->OnStreamReset(rst_frame);
+
+ EXPECT_EQ(1, stream_delegate.remote_reset_count());
+ EXPECT_TRUE(client_peer()->quic_transport()->IsClosedStream(stream_id));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc
new file mode 100644
index 00000000000..71545c64e99
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc
@@ -0,0 +1,88 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+QuicStreamHost::QuicStreamHost() {
+ DETACH_FROM_THREAD(thread_checker_);
+}
+
+QuicStreamHost::~QuicStreamHost() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+void QuicStreamHost::set_proxy(base::WeakPtr<QuicStreamProxy> stream_proxy) {
+ DETACH_FROM_THREAD(thread_checker_);
+ stream_proxy_ = stream_proxy;
+}
+
+void QuicStreamHost::Initialize(QuicTransportHost* transport_host,
+ P2PQuicStream* p2p_stream) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(transport_host);
+ DCHECK(p2p_stream);
+ transport_host_ = transport_host;
+ p2p_stream_ = p2p_stream;
+ p2p_stream_->SetDelegate(this);
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicStreamHost::proxy_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(transport_host_);
+ return transport_host_->proxy_thread();
+}
+
+void QuicStreamHost::Reset() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(p2p_stream_);
+ p2p_stream_->Reset();
+ Delete();
+}
+
+void QuicStreamHost::Finish() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(p2p_stream_);
+ p2p_stream_->Finish();
+ writeable_ = false;
+ if (!readable_ && !writeable_) {
+ Delete();
+ }
+}
+
+void QuicStreamHost::OnRemoteReset() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicStreamProxy::OnRemoteReset, stream_proxy_));
+ Delete();
+}
+
+void QuicStreamHost::OnRemoteFinish() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicStreamProxy::OnRemoteFinish, stream_proxy_));
+ readable_ = false;
+ if (!readable_ && !writeable_) {
+ Delete();
+ }
+}
+
+void QuicStreamHost::Delete() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(transport_host_);
+ // OnRemoveStream will delete |this|.
+ transport_host_->OnRemoveStream(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h
new file mode 100644
index 00000000000..baab847dff6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h"
+
+namespace blink {
+
+class QuicStreamProxy;
+class QuicTransportHost;
+
+// This class is the host side correspondent to the QuicStreamProxy. See the
+// QuicStreamProxy documentation for background. This class lives on the host
+// thread and proxies calls between the QuicStreamProxy and the P2PQuicStream
+// (which is single-threaded).
+//
+// The QuicStreamHost is owned by the QuicTransportHost and constructed when
+// either a new local QUIC stream is created or when a remote QUIC stream has
+// been created. The stream host will be deleted in the following circumstances:
+// 1) Reset() is called.
+// 2) OnRemoteReset() is indicated.
+// 3) Finish() and OnRemoteFinish() have been called.
+// The QuicStreamHost will instruct the QuicTransportHost to delete it when any
+// condition has been met.
+//
+// Since the QuicStreamHost can be constructed from either the proxy or host
+// thread, initialization happens in three steps:
+// 1) QuicStreamHost is constructed.
+// 2) set_proxy is called when a WeakPtr to the corresponding proxy-thread
+// object.
+// 3) Initialize is called on the host thread.
+class QuicStreamHost final : public base::SupportsWeakPtr<QuicStreamHost>,
+ public P2PQuicStream::Delegate {
+ public:
+ QuicStreamHost();
+ ~QuicStreamHost() override;
+
+ // Sets a WeakPtr to the corresponding QuicStreamProxy. This is valid on
+ // either the proxy or host thread. Should happen right after construction.
+ void set_proxy(base::WeakPtr<QuicStreamProxy> stream_proxy);
+
+ // Initializes the QuicStreamHost. Must be called on the host thread.
+ // |transport_host| must outlive this object.
+ void Initialize(QuicTransportHost* transport_host, P2PQuicStream* p2p_stream);
+
+ // The remaining methods can only be called from the host thread and must be
+ // preceded by Initialize().
+
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
+
+ void Reset();
+ void Finish();
+
+ private:
+ // Instruct the QuicTransportHost to remove and delete this stream host.
+ void Delete();
+
+ // P2PQuicStream::Delegate overrides.
+ void OnRemoteReset() override;
+ void OnRemoteFinish() override;
+
+ // Up reference. Owned by QuicTransportProxy.
+ QuicTransportHost* transport_host_ = nullptr;
+ // Forward reference. Owned by P2PQuicTransport.
+ P2PQuicStream* p2p_stream_ = nullptr;
+ // Back reference. Owned by QuicTransportProxy.
+ base::WeakPtr<QuicStreamProxy> stream_proxy_;
+
+ // |readable_| transitions to false when OnRemoteFinish() is called.
+ bool readable_ = true;
+ // |writeable_| transitions to false when Finish() is called.
+ bool writeable_ = true;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_HOST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.cc
new file mode 100644
index 00000000000..e50ebf0925d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.cc
@@ -0,0 +1,91 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+QuicStreamProxy::QuicStreamProxy() {
+ DETACH_FROM_THREAD(thread_checker_);
+}
+
+QuicStreamProxy::~QuicStreamProxy() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+void QuicStreamProxy::set_host(base::WeakPtr<QuicStreamHost> stream_host) {
+ DETACH_FROM_THREAD(thread_checker_);
+ stream_host_ = stream_host;
+}
+
+void QuicStreamProxy::Initialize(QuicTransportProxy* transport_proxy) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(transport_proxy);
+ transport_proxy_ = transport_proxy;
+}
+
+void QuicStreamProxy::set_delegate(Delegate* delegate) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate);
+ delegate_ = delegate;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicStreamProxy::host_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(transport_proxy_);
+ return transport_proxy_->host_thread();
+}
+
+void QuicStreamProxy::Reset() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(*host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicStreamHost::Reset, stream_host_));
+ Delete();
+}
+
+void QuicStreamProxy::Finish() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(*host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicStreamHost::Finish, stream_host_));
+ writeable_ = false;
+ if (!readable_ && !writeable_) {
+ Delete();
+ }
+}
+
+void QuicStreamProxy::OnRemoteReset() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ // Need to copy the |delegate_| member since Delete() will destroy |this|.
+ Delegate* delegate_copy = delegate_;
+ Delete();
+ delegate_copy->OnRemoteReset();
+}
+
+void QuicStreamProxy::OnRemoteFinish() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(delegate_);
+ // Need to copy the |delegate_| member since Delete() will destroy |this|.
+ Delegate* delegate_copy = delegate_;
+ readable_ = false;
+ if (!readable_ && !writeable_) {
+ Delete();
+ }
+ delegate_copy->OnRemoteFinish();
+}
+
+void QuicStreamProxy::Delete() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // OnRemoveStream will delete |this|.
+ transport_proxy_->OnRemoveStream(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h
new file mode 100644
index 00000000000..0d059f635f6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h
@@ -0,0 +1,98 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
+
+namespace blink {
+
+class QuicStreamHost;
+class QuicTransportProxy;
+
+// This class allows interactions with a QUIC stream that runs on a thread
+// different from which it is controlled. All interactions with the QUIC
+// implementation happen asynchronously.
+//
+// The QuicStreamProxy is owned by the QuicTransportProxy and constructed when
+// either a new local QUIC stream is created or when a remote QUIC stream has
+// been created. The stream proxy will be deleted in the following
+// circumstances:
+// 1) Reset() is called.
+// 2) OnRemoteReset() is indicated.
+// 3) Finish() and OnRemoteFinish() have been called.
+// The client is responsible for knowing when any of these conditions have been
+// met and clearing its reference accordingly.
+//
+// Since the QuicStreamProxy can be constructed from either the proxy or host
+// thread, initialization happens in four steps:
+// 1) QuicStreamProxy is constructed.
+// 2) set_host is called with a WeakPtr to the corresponding host-thread object.
+// 3) Initialize is called on the proxy thread.
+// 4) set_delegate is called on the proxy thread.
+class QuicStreamProxy final : public base::SupportsWeakPtr<QuicStreamProxy> {
+ public:
+ class Delegate {
+ public:
+ virtual ~Delegate() = default;
+
+ // Called when the remote side resets the stream.
+ virtual void OnRemoteReset() {}
+ // Called when the remote side finishes the stream.
+ virtual void OnRemoteFinish() {}
+ };
+
+ QuicStreamProxy();
+ ~QuicStreamProxy();
+
+ // Sets a WeakPtr to the corresponding QuicStreamHost. This is valid on either
+ // the proxy or host thread. Should happen right after construction.
+ void set_host(base::WeakPtr<QuicStreamHost> stream_host);
+
+ // Initializes the QuicStreamProxy. Must be called on the proxy thread.
+ // |transport_proxy| must outlive this object.
+ void Initialize(QuicTransportProxy* transport_proxy);
+
+ // Sets the delegate for receiving remote callbacks.
+ void set_delegate(Delegate* delegate);
+
+ // The remaining methods can only be called from the proxy thread and must
+ // be preceded by Initialize().
+
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
+
+ void Reset();
+ void Finish();
+
+ private:
+ // Instruct the QuicTransportProxy to remove and delete this stream proxy.
+ void Delete();
+
+ // Callbacks from QuicStreamHost.
+ friend class QuicStreamHost;
+ void OnRemoteReset();
+ void OnRemoteFinish();
+
+ // Up reference. Owned by the QuicTransportProxy client.
+ QuicTransportProxy* transport_proxy_ = nullptr;
+ // Forward reference. Owned by the QuicTransportHost.
+ base::WeakPtr<QuicStreamHost> stream_host_;
+ // Back reference. Owned by the RTCQuicTransport.
+ Delegate* delegate_ = nullptr;
+
+ // |readable_| transitions to false when OnRemoteFinish() is called.
+ bool readable_ = true;
+ // |writeable_| transitions to false when Finish() is called.
+ bool writeable_ = true;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_STREAM_PROXY_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.cc
new file mode 100644
index 00000000000..cc99a068d8e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.cc
@@ -0,0 +1,139 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+QuicTransportHost::QuicTransportHost(
+ base::WeakPtr<QuicTransportProxy> proxy,
+ std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory)
+ : quic_transport_factory_(std::move(quic_transport_factory)),
+ proxy_(std::move(proxy)) {
+ DETACH_FROM_THREAD(thread_checker_);
+ DCHECK(quic_transport_factory_);
+ DCHECK(proxy_);
+}
+
+QuicTransportHost::~QuicTransportHost() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If the TaskRunner this is getting initialized on is destroyed before
+ // Initialize is called then |ice_transport_host_| may still be null.
+ if (ice_transport_host_) {
+ ice_transport_host_->DisconnectConsumer(this);
+ }
+}
+
+void QuicTransportHost::Initialize(
+ IceTransportHost* ice_transport_host,
+ quic::Perspective perspective,
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(ice_transport_host);
+ DCHECK(!ice_transport_host_);
+ ice_transport_host_ = ice_transport_host;
+ P2PQuicTransportConfig config(
+ this, ice_transport_host->ConnectConsumer(this)->packet_transport(),
+ certificates);
+ config.is_server = (perspective == quic::Perspective::IS_SERVER);
+ quic_transport_ =
+ quic_transport_factory_->CreateQuicTransport(std::move(config));
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicTransportHost::proxy_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return ice_transport_host_->proxy_thread();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicTransportHost::host_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return ice_transport_host_->host_thread();
+}
+
+void QuicTransportHost::Start(
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ quic_transport_->Start(std::move(remote_fingerprints));
+}
+
+void QuicTransportHost::Stop() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ quic_transport_->Stop();
+}
+
+void QuicTransportHost::CreateStream(
+ std::unique_ptr<QuicStreamHost> stream_host) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ P2PQuicStream* p2p_stream = quic_transport_->CreateStream();
+ stream_host->Initialize(this, p2p_stream);
+ stream_hosts_.insert(
+ std::make_pair(stream_host.get(), std::move(stream_host)));
+}
+
+void QuicTransportHost::OnRemoveStream(QuicStreamHost* stream_host_to_remove) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto it = stream_hosts_.find(stream_host_to_remove);
+ DCHECK(it != stream_hosts_.end());
+ stream_hosts_.erase(it);
+}
+
+void QuicTransportHost::OnRemoteStopped() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ stream_hosts_.clear();
+ PostCrossThreadTask(
+ *proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportProxy::OnRemoteStopped, proxy_));
+}
+
+void QuicTransportHost::OnConnectionFailed(const std::string& error_details,
+ bool from_remote) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ stream_hosts_.clear();
+ PostCrossThreadTask(*proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportProxy::OnConnectionFailed,
+ proxy_, error_details, from_remote));
+}
+
+void QuicTransportHost::OnConnected() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportProxy::OnConnected, proxy_));
+}
+
+void QuicTransportHost::OnStream(P2PQuicStream* p2p_stream) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(p2p_stream);
+
+ auto stream_proxy = std::make_unique<QuicStreamProxy>();
+ auto stream_host = std::make_unique<QuicStreamHost>();
+ stream_proxy->set_host(stream_host->AsWeakPtr());
+ stream_host->set_proxy(stream_proxy->AsWeakPtr());
+
+ stream_host->Initialize(this, p2p_stream);
+
+ stream_hosts_.insert(
+ std::make_pair(stream_host.get(), std::move(stream_host)));
+
+ PostCrossThreadTask(*proxy_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportProxy::OnStream, proxy_,
+ WTF::Passed(std::move(stream_proxy))));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h
new file mode 100644
index 00000000000..82b52eeb929
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_
+
+#include <unordered_map>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "net/third_party/quic/core/quic_types.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
+
+namespace blink {
+
+class IceTransportHost;
+class P2PQuicTransportFactory;
+class QuicStreamHost;
+class QuicTransportProxy;
+
+// The host class is the host side correspondent to the QuicTransportProxy. See
+// the QuicTransportProxy documentation for background. This class lives on the
+// host thread and proxies calls between the QuicTransportProxy and the
+// P2PQuicTransport (which is single-threaded).
+//
+// proxy thread host thread
+// +-----------------------+ +-----------------------------------+
+// | | | |
+// | <-> ICE Proxy | =========> | ICE Host <-> P2PTransportChannel |
+// | ^ | <--------- | ^ ^ |
+// | client | | | | | |
+// | v | | v v |
+// | <-> QUIC Proxy | =========> | QUIC Host <-> P2PQuicTransport |
+// | | <--------- | |
+// +-----------------------+ +-----------------------------------+
+//
+// The QuicTransportHost connects to the underlying IceTransportHost in
+// Initialize and disconnects in the destructor. The IceTransportHost must
+// outlive the QuicTransportHost.
+//
+// The Host can be constructed on any thread but after that point all methods
+// must be called on the host thread.
+class QuicTransportHost final : public P2PQuicTransport::Delegate {
+ public:
+ QuicTransportHost(
+ base::WeakPtr<QuicTransportProxy> transport_proxy,
+ std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory);
+ ~QuicTransportHost() override;
+
+ void Initialize(
+ IceTransportHost* ice_transport_host,
+ quic::Perspective perspective,
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates);
+
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
+
+ void Start(
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints);
+ void Stop();
+
+ void CreateStream(std::unique_ptr<QuicStreamHost> stream_host);
+
+ // QuicStreamHost callbacks.
+ void OnRemoveStream(QuicStreamHost* stream_host_to_remove);
+
+ private:
+ // P2PQuicTransport::Delegate overrides.
+ void OnRemoteStopped() override;
+ void OnConnectionFailed(const std::string& error_details,
+ bool from_remote) override;
+ void OnConnected() override;
+ void OnStream(P2PQuicStream* stream) override;
+
+ std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory_;
+ std::unique_ptr<P2PQuicTransport> quic_transport_;
+ base::WeakPtr<QuicTransportProxy> proxy_;
+ IceTransportHost* ice_transport_host_ = nullptr;
+ std::unordered_map<QuicStreamHost*, std::unique_ptr<QuicStreamHost>>
+ stream_hosts_;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_HOST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.cc
new file mode 100644
index 00000000000..af29f9e0546
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.cc
@@ -0,0 +1,151 @@
+// 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 "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+QuicTransportProxy::QuicTransportProxy(
+ Delegate* delegate,
+ IceTransportProxy* ice_transport_proxy,
+ quic::Perspective perspective,
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates,
+ std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory)
+ : host_(nullptr,
+ base::OnTaskRunnerDeleter(ice_transport_proxy->host_thread())),
+ delegate_(delegate),
+ ice_transport_proxy_(ice_transport_proxy),
+ weak_ptr_factory_(this) {
+ DCHECK(delegate_);
+ DCHECK(ice_transport_proxy_);
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
+ ice_transport_proxy->proxy_thread();
+ DCHECK(proxy_thread->BelongsToCurrentThread());
+ // Wait to initialize the host until the weak_ptr_factory_ is initialized.
+ // The QuicTransportHost is constructed on the proxy thread but should only be
+ // interacted with via PostTask to the host thread. The OnTaskRunnerDeleter
+ // (configured above) will ensure it gets deleted on the host thread.
+ host_.reset(new QuicTransportHost(weak_ptr_factory_.GetWeakPtr(),
+ std::move(quic_transport_factory)));
+ // Connect to the IceTransportProxy. This gives us a reference to the
+ // underlying IceTransportHost that should be connected by the
+ // QuicTransportHost on the host thread. It is safe to post it unretained
+ // since the IceTransportHost's ownership is determined by the
+ // IceTransportProxy, and the IceTransportProxy is required to outlive this
+ // object.
+ IceTransportHost* ice_transport_host =
+ ice_transport_proxy->ConnectConsumer(this);
+ PostCrossThreadTask(*host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportHost::Initialize,
+ CrossThreadUnretained(host_.get()),
+ CrossThreadUnretained(ice_transport_host),
+ perspective, certificates));
+}
+
+QuicTransportProxy::~QuicTransportProxy() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ ice_transport_proxy_->DisconnectConsumer(this);
+ // Note: The QuicTransportHost will be deleted on the host thread.
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicTransportProxy::proxy_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return ice_transport_proxy_->proxy_thread();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> QuicTransportProxy::host_thread()
+ const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return ice_transport_proxy_->host_thread();
+}
+
+void QuicTransportProxy::Start(
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportHost::Start,
+ CrossThreadUnretained(host_.get()),
+ WTF::Passed(std::move(remote_fingerprints))));
+}
+
+void QuicTransportProxy::Stop() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(*host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportHost::Stop,
+ CrossThreadUnretained(host_.get())));
+}
+
+QuicStreamProxy* QuicTransportProxy::CreateStream() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto stream_proxy = std::make_unique<QuicStreamProxy>();
+ auto stream_host = std::make_unique<QuicStreamHost>();
+ stream_proxy->set_host(stream_host->AsWeakPtr());
+ stream_host->set_proxy(stream_proxy->AsWeakPtr());
+
+ stream_proxy->Initialize(this);
+
+ PostCrossThreadTask(*host_thread(), FROM_HERE,
+ CrossThreadBind(&QuicTransportHost::CreateStream,
+ CrossThreadUnretained(host_.get()),
+ WTF::Passed(std::move(stream_host))));
+
+ QuicStreamProxy* stream_proxy_ptr = stream_proxy.get();
+ stream_proxies_.insert(
+ std::make_pair(stream_proxy_ptr, std::move(stream_proxy)));
+ return stream_proxy_ptr;
+}
+
+void QuicTransportProxy::OnRemoveStream(
+ QuicStreamProxy* stream_proxy_to_remove) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto it = stream_proxies_.find(stream_proxy_to_remove);
+ DCHECK(it != stream_proxies_.end());
+ stream_proxies_.erase(it);
+}
+
+void QuicTransportProxy::OnConnected() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnConnected();
+}
+
+void QuicTransportProxy::OnRemoteStopped() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ stream_proxies_.clear();
+ delegate_->OnRemoteStopped();
+}
+
+void QuicTransportProxy::OnConnectionFailed(const std::string& error_details,
+ bool from_remote) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnConnectionFailed(error_details, from_remote);
+ stream_proxies_.clear();
+}
+
+void QuicTransportProxy::OnStream(
+ std::unique_ptr<QuicStreamProxy> stream_proxy) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ stream_proxy->Initialize(this);
+
+ QuicStreamProxy* stream_proxy_ptr = stream_proxy.get();
+ stream_proxies_.insert(
+ std::make_pair(stream_proxy_ptr, std::move(stream_proxy)));
+ delegate_->OnStream(stream_proxy_ptr);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h
new file mode 100644
index 00000000000..004aced7f9d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h
@@ -0,0 +1,110 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_
+
+#include <unordered_map>
+#include <vector>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "net/third_party/quic/core/quic_types.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace rtc {
+class RTCCertificate;
+struct SSLFingerprint;
+} // namespace rtc
+
+namespace blink {
+
+class IceTransportProxy;
+class QuicStreamProxy;
+class QuicTransportHost;
+class P2PQuicTransportFactory;
+
+// This class allows the QUIC implementation (P2PQuicTransport) to run on a
+// thread different from the thread from which it is controlled. All
+// interactions with the QUIC implementation happen asynchronously.
+//
+// The QuicTransportProxy is intended to be used with an IceTransportProxy --
+// see the IceTransportProxy class documentation for background and terms. The
+// proxy and host threads used with the QuicTransportProxy should be the same as
+// the ones used with the connected IceTransportProxy.
+class QuicTransportProxy final {
+ public:
+ // Delegate for receiving callbacks from the QUIC implementation. These all
+ // run on the proxy thread.
+ class Delegate {
+ public:
+ virtual ~Delegate() = default;
+
+ // Called when the QUIC handshake finishes and fingerprints have been
+ // verified.
+ virtual void OnConnected() {}
+ // Called when the remote side has indicated it is closed.
+ virtual void OnRemoteStopped() {}
+ // Called when the connection is closed due to a QUIC error. This can happen
+ // locally by the framer or remotely by the peer.
+ virtual void OnConnectionFailed(const std::string& error_details,
+ bool from_remote) {}
+ // Called when the remote side has created a new stream.
+ virtual void OnStream(QuicStreamProxy* stream_proxy) {}
+ };
+
+ // Construct a Proxy with the underlying QUIC implementation running on the
+ // same thread as the IceTransportProxy. Callbacks will be serviced by the
+ // given delegate.
+ // The delegate and IceTransportProxy must outlive the QuicTransportProxy.
+ // The QuicTransportProxy will immediately connect to the given
+ // IceTransportProxy; it can be disconnected by destroying the
+ // QuicTransportProxy object.
+ QuicTransportProxy(
+ Delegate* delegate,
+ IceTransportProxy* ice_transport_proxy,
+ quic::Perspective perspective,
+ const std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>& certificates,
+ std::unique_ptr<P2PQuicTransportFactory> quic_transport_factory);
+ ~QuicTransportProxy();
+
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread() const;
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread() const;
+
+ void Start(
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> remote_fingerprints);
+ void Stop();
+
+ QuicStreamProxy* CreateStream();
+
+ // QuicStreamProxy callbacks.
+ void OnRemoveStream(QuicStreamProxy* stream_proxy);
+
+ private:
+ // Callbacks from QuicTransportHost.
+ friend class QuicTransportHost;
+ void OnConnected();
+ void OnRemoteStopped();
+ void OnConnectionFailed(const std::string& error_details, bool from_remote);
+ void OnStream(std::unique_ptr<QuicStreamProxy> stream_proxy);
+
+ // Since the Host is deleted on the host thread (Via OnTaskRunnerDeleter), as
+ // long as this is alive it is safe to post tasks to it (using unretained).
+ std::unique_ptr<QuicTransportHost, base::OnTaskRunnerDeleter> host_;
+ Delegate* const delegate_;
+ IceTransportProxy* ice_transport_proxy_;
+ std::unordered_map<QuicStreamProxy*, std::unique_ptr<QuicStreamProxy>>
+ stream_proxies_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ // Must be the last member.
+ base::WeakPtrFactory<QuicTransportProxy> weak_ptr_factory_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_QUIC_TRANSPORT_PROXY_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
index 7f19fb64954..73ab10b27a1 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
@@ -8,10 +8,12 @@
// This file defines specializations for the CrossThreadCopier that allow WebRTC
// types to be passed across threads using their copy constructors.
+#include <memory>
#include <set>
#include <vector>
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
+#include "third_party/webrtc/rtc_base/scoped_ref_ptr.h"
namespace cricket {
class Candidate;
@@ -20,12 +22,26 @@ struct RelayServerConfig;
} // namespace cricket
namespace rtc {
+class RTCCertificate;
class SocketAddress;
}
namespace blink {
template <>
+struct CrossThreadCopier<std::string>
+ : public CrossThreadCopierPassThrough<std::string> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename T, typename Allocator>
+struct CrossThreadCopier<std::vector<std::unique_ptr<T>, Allocator>> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = std::vector<std::unique_ptr<T>, Allocator>;
+ static Type Copy(Type vector) { return std::move(vector); }
+};
+
+template <>
struct CrossThreadCopier<cricket::IceParameters>
: public CrossThreadCopierPassThrough<cricket::IceParameters> {
STATIC_ONLY(CrossThreadCopier);
@@ -45,11 +61,31 @@ struct CrossThreadCopier<std::vector<cricket::RelayServerConfig>>
};
template <>
+struct CrossThreadCopier<std::vector<cricket::Candidate>>
+ : public CrossThreadCopierPassThrough<std::vector<cricket::Candidate>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
struct CrossThreadCopier<cricket::Candidate>
: public CrossThreadCopierPassThrough<cricket::Candidate> {
STATIC_ONLY(CrossThreadCopier);
};
+template <>
+struct CrossThreadCopier<std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>>
+ : public CrossThreadCopierPassThrough<
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<std::pair<cricket::Candidate, cricket::Candidate>>
+ : public CrossThreadCopierPassThrough<
+ std::pair<cricket::Candidate, cricket::Candidate>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl
index e80074f057d..44ced3eb309 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl
@@ -29,7 +29,7 @@
*/
// https://w3c.github.io/webrtc-pc/#rtccertificate-interface
-[Exposed=Window]
+[Exposed=Window, Serializable]
interface RTCCertificate {
// The expiration time in ms relative to epoch, 1970-01-01T00:00:00Z.
readonly attribute DOMTimeStamp expires;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
index 8f44593af4f..d312c8030e0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
@@ -35,15 +35,14 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
static const int kMinToneDurationMs = 40;
static const int kDefaultToneDurationMs = 100;
static const int kMaxToneDurationMs = 6000;
-// TODO(hta): Adjust kMinInterToneGapMs to 30 once WebRTC code has changed
-// CL in progress: https://webrtc-review.googlesource.com/c/src/+/55260
-static const int kMinInterToneGapMs = 50;
+static const int kMinInterToneGapMs = 30;
static const int kMaxInterToneGapMs = 6000;
static const int kDefaultInterToneGapMs = 70;
@@ -58,10 +57,7 @@ RTCDTMFSender::RTCDTMFSender(ExecutionContext* context,
std::unique_ptr<WebRTCDTMFSenderHandler> handler)
: ContextLifecycleObserver(context),
handler_(std::move(handler)),
- stopped_(false),
- scheduled_event_timer_(context->GetTaskRunner(TaskType::kNetworking),
- this,
- &RTCDTMFSender::ScheduledEventTimerFired) {
+ stopped_(false) {
handler_->SetClient(this);
}
@@ -79,7 +75,7 @@ bool RTCDTMFSender::canInsertDTMF() const {
}
String RTCDTMFSender::toneBuffer() const {
- return handler_->CurrentToneBuffer();
+ return tone_buffer_;
}
void RTCDTMFSender::insertDTMF(const String& tones,
@@ -99,8 +95,6 @@ void RTCDTMFSender::insertDTMF(const String& tones,
int inter_tone_gap,
ExceptionState& exception_state) {
// https://w3c.github.io/webrtc-pc/#dom-rtcdtmfsender-insertdtmf
- // TODO(hta): Add check on transceiver's "stopped" and "currentDirection"
- // attributes
if (!canInsertDTMF()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The 'canInsertDTMF' attribute is false: "
@@ -116,23 +110,61 @@ void RTCDTMFSender::insertDTMF(const String& tones,
}
// Spec: Clamp the duration to between 40 and 6000 ms
- duration = std::max(duration, kMinToneDurationMs);
- duration = std::min(duration, kMaxToneDurationMs);
+ duration_ = std::max(duration, kMinToneDurationMs);
+ duration_ = std::min(duration_, kMaxToneDurationMs);
// Spec: Clamp the inter-tone gap to between 30 and 6000 ms
- inter_tone_gap = std::max(inter_tone_gap, kMinInterToneGapMs);
- inter_tone_gap = std::min(inter_tone_gap, kMaxInterToneGapMs);
+ inter_tone_gap_ = std::max(inter_tone_gap, kMinInterToneGapMs);
+ inter_tone_gap_ = std::min(inter_tone_gap_, kMaxInterToneGapMs);
// Spec: a-d should be represented in the tone buffer as A-D
- if (!handler_->InsertDTMF(tones.UpperASCII(), duration, inter_tone_gap)) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "Could not send provided tones, '" + tones + "'.");
+ tone_buffer_ = tones.UpperASCII();
+
+ if (tone_buffer_.IsEmpty()) {
+ return;
+ }
+ if (!playout_task_is_scheduled_) {
+ playout_task_is_scheduled_ = true;
+ GetExecutionContext()
+ ->GetTaskRunner(TaskType::kNetworking)
+ ->PostTask(FROM_HERE, WTF::Bind(&RTCDTMFSender::PlayoutTask,
+ WrapPersistent(this)));
+ }
+}
+
+void RTCDTMFSender::PlayoutTask() {
+ playout_task_is_scheduled_ = false;
+ // TODO(crbug.com/891638): Add check on transceiver's "stopped"
+ // and "currentDirection" attributes as per spec.
+ if (tone_buffer_.IsEmpty()) {
+ Member<Event> event = RTCDTMFToneChangeEvent::Create("");
+ DispatchEvent(*event.Release());
+ return;
+ }
+ WebString this_tone = tone_buffer_.Substring(0, 1);
+ tone_buffer_ = tone_buffer_.Substring(1, tone_buffer_.length() - 1);
+ // InsertDTMF handles both tones and ",", and calls DidPlayTone after
+ // the specified delay.
+ if (!handler_->InsertDTMF(this_tone, duration_, inter_tone_gap_)) {
+ LOG(ERROR) << "DTMF: Could not send provided tone, '" << this_tone.Ascii()
+ << "'.";
return;
}
+ playout_task_is_scheduled_ = true;
+ Member<Event> event = RTCDTMFToneChangeEvent::Create(this_tone);
+ DispatchEvent(*event.Release());
}
void RTCDTMFSender::DidPlayTone(const WebString& tone) {
- ScheduleDispatchEvent(RTCDTMFToneChangeEvent::Create(tone));
+ // We're using the DidPlayTone with an empty buffer to signal the
+ // end of the tone.
+ if (tone.IsEmpty()) {
+ GetExecutionContext()
+ ->GetTaskRunner(TaskType::kNetworking)
+ ->PostDelayedTask(
+ FROM_HERE,
+ WTF::Bind(&RTCDTMFSender::PlayoutTask, WrapPersistent(this)),
+ base::TimeDelta::FromMilliseconds(inter_tone_gap_));
+ }
}
const AtomicString& RTCDTMFSender::InterfaceName() const {
@@ -148,27 +180,7 @@ void RTCDTMFSender::ContextDestroyed(ExecutionContext*) {
handler_->SetClient(nullptr);
}
-void RTCDTMFSender::ScheduleDispatchEvent(Event* event) {
- scheduled_events_.push_back(event);
-
- if (!scheduled_event_timer_.IsActive())
- scheduled_event_timer_.StartOneShot(TimeDelta(), FROM_HERE);
-}
-
-void RTCDTMFSender::ScheduledEventTimerFired(TimerBase*) {
- if (stopped_)
- return;
-
- HeapVector<Member<Event>> events;
- events.swap(scheduled_events_);
-
- HeapVector<Member<Event>>::iterator it = events.begin();
- for (; it != events.end(); ++it)
- DispatchEvent(*it->Release());
-}
-
void RTCDTMFSender::Trace(blink::Visitor* visitor) {
- visitor->Trace(scheduled_events_);
EventTargetWithInlineData::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
index c356c957487..1ee1ead6834 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
@@ -75,18 +75,17 @@ class RTCDTMFSender final : public EventTargetWithInlineData,
std::unique_ptr<WebRTCDTMFSenderHandler>);
void Dispose();
- void ScheduleDispatchEvent(Event*);
- void ScheduledEventTimerFired(TimerBase*);
-
// WebRTCDTMFSenderHandlerClient
+ void PlayoutTask();
void DidPlayTone(const WebString&) override;
std::unique_ptr<WebRTCDTMFSenderHandler> handler_;
bool stopped_;
-
- TaskRunnerTimer<RTCDTMFSender> scheduled_event_timer_;
- HeapVector<Member<Event>> scheduled_events_;
+ String tone_buffer_;
+ int duration_;
+ int inter_tone_gap_;
+ bool playout_task_is_scheduled_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
index 08aa5b19001..b5715c8dee9 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_CANDIDATE_H_
#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -43,7 +44,7 @@ class ExecutionContext;
class ScriptState;
class ScriptValue;
-class RTCIceCandidate final : public ScriptWrappable {
+class MODULES_EXPORT RTCIceCandidate final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index 117eccf66e5..2f4c4d6d152 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -5,11 +5,13 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_cross_thread_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
@@ -17,6 +19,8 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/webrtc/api/jsepicecandidate.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/p2p/base/portallocator.h"
@@ -47,25 +51,71 @@ RTCIceCandidate* ConvertToRtcIceCandidate(const cricket::Candidate& candidate) {
WebString::FromUTF8(webrtc::SdpSerializeCandidate(candidate)), "", 0));
}
+class DefaultIceTransportAdapterCrossThreadFactory
+ : public IceTransportAdapterCrossThreadFactory {
+ public:
+ void InitializeOnMainThread() override {
+ DCHECK(!port_allocator_);
+ DCHECK(!worker_thread_rtc_thread_);
+ port_allocator_ = Platform::Current()->CreateWebRtcPortAllocator(
+ WebLocalFrame::FrameForCurrentContext());
+ worker_thread_rtc_thread_ =
+ Platform::Current()->GetWebRtcWorkerThreadRtcThread();
+ }
+
+ std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread(
+ IceTransportAdapter::Delegate* delegate) override {
+ DCHECK(port_allocator_);
+ DCHECK(worker_thread_rtc_thread_);
+ return std::make_unique<IceTransportAdapterImpl>(
+ delegate, std::move(port_allocator_), worker_thread_rtc_thread_);
+ }
+
+ private:
+ std::unique_ptr<cricket::PortAllocator> port_allocator_;
+ rtc::Thread* worker_thread_rtc_thread_ = nullptr;
+};
+
} // namespace
RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) {
- return new RTCIceTransport(context);
-}
-
-RTCIceTransport::RTCIceTransport(ExecutionContext* context)
+ LocalFrame* frame = To<Document>(context)->GetFrame();
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
+ frame->GetTaskRunner(TaskType::kNetworking);
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread =
+ Platform::Current()->GetWebRtcWorkerThread();
+ return new RTCIceTransport(
+ context, std::move(proxy_thread), std::move(host_thread),
+ std::make_unique<DefaultIceTransportAdapterCrossThreadFactory>());
+}
+
+RTCIceTransport* RTCIceTransport::Create(
+ ExecutionContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory) {
+ return new RTCIceTransport(context, std::move(proxy_thread),
+ std::move(host_thread),
+ std::move(adapter_factory));
+}
+
+RTCIceTransport::RTCIceTransport(
+ ExecutionContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory)
: ContextLifecycleObserver(context) {
- Document* document = ToDocument(GetExecutionContext());
- LocalFrame* frame = document->GetFrame();
- DCHECK(frame);
+ DCHECK(context);
+ DCHECK(proxy_thread);
+ DCHECK(host_thread);
+ DCHECK(adapter_factory);
+ DCHECK(proxy_thread->BelongsToCurrentThread());
- std::unique_ptr<cricket::PortAllocator> port_allocator =
- Platform::Current()->CreateWebRtcPortAllocator(
- WebLocalFrame::FrameForCurrentContext());
+ LocalFrame* frame = To<Document>(context)->GetFrame();
+ DCHECK(frame);
proxy_.reset(new IceTransportProxy(
- frame->GetFrameScheduler(), Platform::Current()->GetWebRtcWorkerThread(),
- Platform::Current()->GetWebRtcWorkerThreadRtcThread(), this,
- std::move(port_allocator)));
+ frame->GetFrameScheduler(), std::move(proxy_thread),
+ std::move(host_thread), this, std::move(adapter_factory)));
GenerateLocalParameters();
}
@@ -74,6 +124,29 @@ RTCIceTransport::~RTCIceTransport() {
DCHECK(!proxy_);
}
+bool RTCIceTransport::HasConsumer() const {
+ return consumer_;
+}
+
+IceTransportProxy* RTCIceTransport::ConnectConsumer(
+ RTCQuicTransport* consumer) {
+ DCHECK(consumer);
+ DCHECK(proxy_);
+ if (!consumer_) {
+ consumer_ = consumer;
+ } else {
+ DCHECK_EQ(consumer_, consumer);
+ }
+ return proxy_.get();
+}
+
+void RTCIceTransport::DisconnectConsumer(RTCQuicTransport* consumer) {
+ DCHECK(consumer);
+ DCHECK(proxy_);
+ DCHECK_EQ(consumer, consumer_);
+ consumer_ = nullptr;
+}
+
String RTCIceTransport::role() const {
switch (role_) {
case cricket::ICEROLE_CONTROLLING:
@@ -187,6 +260,17 @@ ConvertIceServers(const HeapVector<RTCIceServer>& ice_servers) {
return converted_ice_servers;
}
+static IceTransportPolicy IceTransportPolicyFromString(const String& str) {
+ if (str == "relay") {
+ return IceTransportPolicy::kRelay;
+ }
+ if (str == "all") {
+ return IceTransportPolicy::kAll;
+ }
+ NOTREACHED();
+ return IceTransportPolicy::kAll;
+}
+
void RTCIceTransport::gather(const RTCIceGatherOptions& options,
ExceptionState& exception_state) {
if (RaiseExceptionIfClosed(exception_state)) {
@@ -214,14 +298,9 @@ void RTCIceTransport::gather(const RTCIceGatherOptions& options,
return;
}
gathering_state_ = cricket::kIceGatheringGathering;
- uint32_t candidate_filter = cricket::CF_ALL;
- if (options.gatherPolicy() == "relay") {
- candidate_filter = cricket::CF_RELAY;
- } else {
- DCHECK_EQ(options.gatherPolicy(), "all");
- }
proxy_->StartGathering(ConvertIceParameters(local_parameters_), stun_servers,
- turn_servers, candidate_filter);
+ turn_servers,
+ IceTransportPolicyFromString(options.gatherPolicy()));
}
static cricket::IceRole IceRoleFromString(const String& role_string) {
@@ -267,21 +346,26 @@ void RTCIceTransport::start(const RTCIceParameters& remote_parameters,
}
if (!remote_parameters_) {
// Calling start() for the first time.
- proxy_->SetRole(role);
role_ = role;
if (remote_candidates_.size() > 0) {
- for (RTCIceCandidate* remote_candidate : remote_candidates_) {
- // This conversion is safe since we throw an exception in
- // addRemoteCandidate on malformed ICE candidates.
- proxy_->AddRemoteCandidate(
- *ConvertToCricketIceCandidate(*remote_candidate));
- }
state_ = RTCIceTransportState::kChecking;
}
+ std::vector<cricket::Candidate> initial_remote_candidates;
+ for (RTCIceCandidate* remote_candidate : remote_candidates_) {
+ // This conversion is safe since we throw an exception in
+ // addRemoteCandidate on malformed ICE candidates.
+ initial_remote_candidates.push_back(
+ *ConvertToCricketIceCandidate(*remote_candidate));
+ }
+ proxy_->Start(ConvertIceParameters(remote_parameters), role,
+ initial_remote_candidates);
+ if (consumer_) {
+ consumer_->OnTransportStarted();
+ }
} else {
- proxy_->ClearRemoteCandidates();
remote_candidates_.clear();
state_ = RTCIceTransportState::kNew;
+ proxy_->HandleRemoteRestart(ConvertIceParameters(remote_parameters));
}
remote_parameters_ = remote_parameters;
}
@@ -290,7 +374,13 @@ void RTCIceTransport::stop() {
if (IsClosed()) {
return;
}
+ if (HasConsumer()) {
+ consumer_->stop();
+ }
+ // Stopping the consumer should cause it to disconnect.
+ DCHECK(!HasConsumer());
state_ = RTCIceTransportState::kClosed;
+ selected_candidate_pair_ = base::nullopt;
proxy_.reset();
}
@@ -366,9 +456,25 @@ void RTCIceTransport::OnStateChanged(cricket::IceTransportState new_state) {
return;
}
state_ = local_new_state;
+ if (state_ == RTCIceTransportState::kFailed) {
+ selected_candidate_pair_ = base::nullopt;
+ }
DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
+void RTCIceTransport::OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) {
+ RTCIceCandidate* local =
+ ConvertToRtcIceCandidate(selected_candidate_pair.first);
+ RTCIceCandidate* remote =
+ ConvertToRtcIceCandidate(selected_candidate_pair.second);
+ selected_candidate_pair_ = RTCIceCandidatePair();
+ selected_candidate_pair_->setLocal(local);
+ selected_candidate_pair_->setRemote(remote);
+ DispatchEvent(*Event::Create(EventTypeNames::selectedcandidatepairchange));
+}
+
bool RTCIceTransport::RaiseExceptionIfClosed(
ExceptionState& exception_state) const {
if (IsClosed()) {
@@ -402,6 +508,7 @@ void RTCIceTransport::Trace(blink::Visitor* visitor) {
visitor->Trace(local_candidates_);
visitor->Trace(remote_candidates_);
visitor->Trace(selected_candidate_pair_);
+ visitor->Trace(consumer_);
EventTargetWithInlineData::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
index fa8e307d1f9..2a39f0c5dbc 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -19,6 +19,8 @@ namespace blink {
class ExceptionState;
class RTCIceCandidate;
class RTCIceGatherOptions;
+class IceTransportAdapterCrossThreadFactory;
+class RTCQuicTransport;
enum class RTCIceTransportState {
kNew,
@@ -43,17 +45,40 @@ class MODULES_EXPORT RTCIceTransport final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<RTCIceTransport>,
public ContextLifecycleObserver,
- private IceTransportProxy::Delegate {
+ public IceTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCIceTransport);
public:
static RTCIceTransport* Create(ExecutionContext* context);
+ static RTCIceTransport* Create(
+ ExecutionContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
~RTCIceTransport() override;
+ // Returns true if start() has been called.
+ bool IsStarted() const { return role_ != cricket::ICEROLE_UNKNOWN; }
+
+ // Returns the role specified in start().
+ cricket::IceRole GetRole() const { return role_; }
+
+ // Returns true if the RTCIceTransport is in a terminal state.
bool IsClosed() const { return state_ == RTCIceTransportState::kClosed; }
+ // An RTCQuicTransport can be connected to this RTCIceTransport. Only one can
+ // be connected at a time. The consumer will be automatically disconnected
+ // if stop() is called on this object. Otherwise, the RTCQuicTransport is
+ // responsible for disconnecting itself when it is done.
+ // ConnectConsumer returns an IceTransportProxy that can be used to connect
+ // a QuicTransportProxy. It may be called repeatedly with the same
+ // RTCQuicTransport.
+ bool HasConsumer() const;
+ IceTransportProxy* ConnectConsumer(RTCQuicTransport* consumer);
+ void DisconnectConsumer(RTCQuicTransport* consumer);
+
// rtc_ice_transport.idl
String role() const;
String state() const;
@@ -74,6 +99,7 @@ class MODULES_EXPORT RTCIceTransport final
ExceptionState& exception_state);
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(gatheringstatechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(selectedcandidatepairchange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate);
// EventTarget overrides.
@@ -90,12 +116,19 @@ class MODULES_EXPORT RTCIceTransport final
void Trace(blink::Visitor* visitor) override;
private:
- explicit RTCIceTransport(ExecutionContext* context);
+ explicit RTCIceTransport(
+ ExecutionContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
// IceTransportProxy::Delegate overrides.
void OnGatheringStateChanged(cricket::IceGatheringState new_state) override;
void OnCandidateGathered(const cricket::Candidate& candidate) override;
void OnStateChanged(cricket::IceTransportState new_state) override;
+ void OnSelectedCandidatePairChanged(
+ const std::pair<cricket::Candidate, cricket::Candidate>&
+ selected_candidate_pair) override;
// Fills in |local_parameters_| with a random usernameFragment and a random
// password.
@@ -115,6 +148,8 @@ class MODULES_EXPORT RTCIceTransport final
base::Optional<RTCIceCandidatePair> selected_candidate_pair_;
+ Member<RTCQuicTransport> consumer_;
+
// Handle to the WebRTC ICE transport. Created when this binding is
// constructed and deleted once network traffic should be stopped.
std::unique_ptr<IceTransportProxy> proxy_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
index a2aca1fe626..76656b1b2cf 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
@@ -47,7 +47,7 @@ enum RTCIceGatheringState {
RTCIceParameters? getRemoteParameters();
attribute EventHandler onstatechange;
attribute EventHandler ongatheringstatechange;
- // TODO(crbug.com/864871): Implement onselectedcandidatepairchange.
+ attribute EventHandler onselectedcandidatepairchange;
// The following is defined in the WebRTC-ICE extension specification.
// https://w3c.github.io/webrtc-ice/#rtcicetransport*
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
new file mode 100644
index 00000000000..1dcb46312f3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
@@ -0,0 +1,573 @@
+// 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.
+
+// This file tests the RTCIceTransport Blink bindings, IceTransportProxy and
+// IceTransportHost by mocking out the underlying IceTransportAdapter.
+// Everything is run on a single thread but with separate TestSimpleTaskRunners
+// for the main thread / worker thread.
+
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_ice_transport_adapter_cross_thread_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
+#include "third_party/webrtc/pc/webrtcsdp.h"
+
+namespace blink {
+namespace {
+
+using testing::_;
+using testing::Assign;
+using testing::AllOf;
+using testing::DoDefault;
+using testing::ElementsAre;
+using testing::Field;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Mock;
+using testing::StrEq;
+using testing::StrNe;
+
+constexpr char kRemoteUsernameFragment1[] = "usernameFragment";
+constexpr char kRemotePassword1[] = "password";
+
+constexpr char kRemoteUsernameFragment2[] = "secondUsernameFragment";
+constexpr char kRemotePassword2[] = "secondPassword";
+
+RTCIceParameters CreateRemoteRTCIceParameters2() {
+ RTCIceParameters ice_parameters;
+ ice_parameters.setUsernameFragment(kRemoteUsernameFragment2);
+ ice_parameters.setPassword(kRemotePassword2);
+ return ice_parameters;
+}
+
+constexpr char kLocalIceCandidateStr1[] =
+ "candidate:a0+B/1 1 udp 2130706432 192.168.1.5 1234 typ host generation 2";
+constexpr char kRemoteIceCandidateStr1[] =
+ "candidate:a0+B/2 1 udp 2130706432 ::1 1238 typ host generation 2";
+constexpr char kRemoteIceCandidateStr2[] =
+ "candidate:a0+B/3 1 udp 2130706432 74.125.127.126 2345 typ srflx raddr "
+ "192.168.1.5 rport 2346 generation 2";
+
+RTCIceCandidate* RTCIceCandidateFromString(V8TestingScope& scope,
+ const String& candidate_str) {
+ RTCIceCandidateInit init;
+ init.setCandidate(candidate_str);
+ return RTCIceCandidate::Create(scope.GetExecutionContext(), init,
+ ASSERT_NO_EXCEPTION);
+}
+
+cricket::Candidate CricketCandidateFromString(
+ const std::string& candidate_str) {
+ cricket::Candidate candidate;
+ bool success =
+ webrtc::SdpDeserializeCandidate("", candidate_str, &candidate, nullptr);
+ DCHECK(success);
+ return candidate;
+}
+
+} // namespace
+
+// static
+RTCIceParameters RTCIceTransportTest::CreateRemoteRTCIceParameters1() {
+ RTCIceParameters ice_parameters;
+ ice_parameters.setUsernameFragment(kRemoteUsernameFragment1);
+ ice_parameters.setPassword(kRemotePassword1);
+ return ice_parameters;
+}
+
+RTCIceTransportTest::RTCIceTransportTest()
+ : main_thread_(new base::TestSimpleTaskRunner()),
+ worker_thread_(new base::TestSimpleTaskRunner()) {}
+
+RTCIceTransportTest::~RTCIceTransportTest() {
+ // When the V8TestingScope is destroyed at the end of a test, it will call
+ // ContextDestroyed on the RTCIceTransport which will queue a task to delete
+ // the IceTransportAdapter. RunUntilIdle() here ensures that the task will
+ // be executed and the IceTransportAdapter deleted before finishing the
+ // test.
+ RunUntilIdle();
+
+ // Explicitly verify expectations of garbage collected mock objects.
+ for (auto mock : mock_event_listeners_) {
+ Mock::VerifyAndClear(mock);
+ }
+}
+
+void RTCIceTransportTest::RunUntilIdle() {
+ while (worker_thread_->HasPendingTask() || main_thread_->HasPendingTask()) {
+ worker_thread_->RunPendingTasks();
+ main_thread_->RunPendingTasks();
+ }
+}
+
+RTCIceTransport* RTCIceTransportTest::CreateIceTransport(
+ V8TestingScope& scope) {
+ return CreateIceTransport(
+ scope, std::make_unique<MockIceTransportAdapter>(
+ std::make_unique<MockP2PQuicPacketTransport>()));
+}
+
+RTCIceTransport* RTCIceTransportTest::CreateIceTransport(
+ V8TestingScope& scope,
+ IceTransportAdapter::Delegate** delegate_out) {
+ return CreateIceTransport(scope, std::make_unique<MockIceTransportAdapter>(),
+ delegate_out);
+}
+
+RTCIceTransport* RTCIceTransportTest::CreateIceTransport(
+ V8TestingScope& scope,
+ std::unique_ptr<MockIceTransportAdapter> mock,
+ IceTransportAdapter::Delegate** delegate_out) {
+ if (delegate_out) {
+ // Ensure the caller has not left the delegate_out value floating.
+ DCHECK_EQ(nullptr, *delegate_out);
+ }
+ return RTCIceTransport::Create(
+ scope.GetExecutionContext(), main_thread_, worker_thread_,
+ std::make_unique<MockIceTransportAdapterCrossThreadFactory>(
+ std::move(mock), delegate_out));
+}
+
+MockEventListener* RTCIceTransportTest::CreateMockEventListener() {
+ MockEventListener* event_listener = new MockEventListener();
+ mock_event_listeners_.push_back(event_listener);
+ return event_listener;
+}
+
+// Test that calling gather({}) calls StartGathering with non-empty local
+// parameters.
+TEST_F(RTCIceTransportTest, GatherStartsGatheringWithNonEmptyLocalParameters) {
+ V8TestingScope scope;
+
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ auto ice_parameters_not_empty =
+ AllOf(Field(&cricket::IceParameters::ufrag, StrNe("")),
+ Field(&cricket::IceParameters::pwd, StrNe("")));
+ EXPECT_CALL(*mock, StartGathering(ice_parameters_not_empty, _, _, _))
+ .Times(1);
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("all");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling gather({ gatherPolicy: 'all' }) calls StartGathering with
+// IceTransportPolicy::kAll.
+TEST_F(RTCIceTransportTest, GatherIceTransportPolicyAll) {
+ V8TestingScope scope;
+
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ EXPECT_CALL(*mock, StartGathering(_, _, _, IceTransportPolicy::kAll))
+ .Times(1);
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("all");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling gather({ gatherPolicy: 'relay' }) calls StartGathering with
+// IceTransportPolicy::kRelay.
+TEST_F(RTCIceTransportTest, GatherIceTransportPolicyRelay) {
+ V8TestingScope scope;
+
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ EXPECT_CALL(*mock, StartGathering(_, _, _, IceTransportPolicy::kRelay))
+ .Times(1);
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("relay");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling stop() deletes the underlying IceTransportAdapter.
+TEST_F(RTCIceTransportTest, StopDeletesIceTransportAdapter) {
+ V8TestingScope scope;
+
+ bool mock_deleted = false;
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ EXPECT_CALL(*mock, Die()).WillOnce(Assign(&mock_deleted, true));
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("all");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+
+ ice_transport->stop();
+ RunUntilIdle();
+
+ EXPECT_TRUE(mock_deleted);
+}
+
+// Test that the IceTransportAdapter is deleted on ContextDestroyed.
+TEST_F(RTCIceTransportTest, ContextDestroyedDeletesIceTransportAdapter) {
+ V8TestingScope scope;
+
+ bool mock_deleted = false;
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ EXPECT_CALL(*mock, Die()).WillOnce(Assign(&mock_deleted, true));
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("all");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+
+ ice_transport->ContextDestroyed(scope.GetExecutionContext());
+ RunUntilIdle();
+
+ EXPECT_TRUE(mock_deleted);
+}
+
+// Test that calling OnGatheringStateChanged(complete) on the delegate fires a
+// null icecandidate event and a gatheringstatechange event.
+TEST_F(RTCIceTransportTest, OnGatheringStateChangedCompleteFiresEvents) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ RTCIceGatherOptions options;
+ options.setGatherPolicy("all");
+ ice_transport->gather(options, ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> ice_candidate_listener =
+ CreateMockEventListener();
+ Persistent<MockEventListener> gathering_state_change_listener =
+ CreateMockEventListener();
+ {
+ InSequence dummy;
+ EXPECT_CALL(*ice_candidate_listener, handleEvent(_, _))
+ .WillOnce(Invoke([ice_transport](ExecutionContext*, Event* event) {
+ auto* ice_event = static_cast<RTCPeerConnectionIceEvent*>(event);
+ EXPECT_EQ(nullptr, ice_event->candidate());
+ }));
+ EXPECT_CALL(*gathering_state_change_listener, handleEvent(_, _))
+ .WillOnce(InvokeWithoutArgs([ice_transport] {
+ EXPECT_EQ("complete", ice_transport->gatheringState());
+ }));
+ }
+ ice_transport->addEventListener(EventTypeNames::icecandidate,
+ ice_candidate_listener);
+ ice_transport->addEventListener(EventTypeNames::gatheringstatechange,
+ gathering_state_change_listener);
+ delegate->OnGatheringStateChanged(cricket::kIceGatheringComplete);
+
+ RunUntilIdle();
+}
+
+// Test that calling start() calls Start on the IceTransportAdapter with the
+// correct arguments when no remote candidates had previously been added.
+TEST_F(RTCIceTransportTest,
+ StartPassesRemoteParametersAndRoleAndInitialRemoteCandidates) {
+ V8TestingScope scope;
+
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ auto ice_parameters_equal = AllOf(
+ Field(&cricket::IceParameters::ufrag, StrEq(kRemoteUsernameFragment1)),
+ Field(&cricket::IceParameters::pwd, StrEq(kRemotePassword1)));
+ EXPECT_CALL(*mock, Start(ice_parameters_equal, cricket::ICEROLE_CONTROLLING,
+ ElementsAre()))
+ .Times(1);
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+}
+
+MATCHER_P(SerializedIceCandidateEq, candidate_str, "") {
+ std::string arg_str = webrtc::SdpSerializeCandidate(arg);
+ *result_listener << "Expected ICE candidate that serializes to: "
+ << candidate_str << "; got: " << arg_str;
+ return arg_str == candidate_str;
+}
+
+// Test that remote candidates are not passed to the IceTransportAdapter until
+// start() is called.
+TEST_F(RTCIceTransportTest, RemoteCandidatesNotPassedUntilStartCalled) {
+ V8TestingScope scope;
+
+ auto mock = std::make_unique<MockIceTransportAdapter>();
+ EXPECT_CALL(
+ *mock,
+ Start(_, _,
+ ElementsAre(SerializedIceCandidateEq(kRemoteIceCandidateStr1))))
+ .Times(1);
+ EXPECT_CALL(*mock, AddRemoteCandidate(_)).Times(0);
+
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(mock));
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+}
+
+// Test that receiving an OnStateChanged callback with the completed state
+// updates the RTCIceTransport state to 'connected' and fires a statechange
+// event.
+TEST_F(RTCIceTransportTest, OnStateChangedCompletedUpdatesStateAndFiresEvent) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> event_listener = CreateMockEventListener();
+ EXPECT_CALL(*event_listener, handleEvent(_, _))
+ .WillOnce(InvokeWithoutArgs(
+ [ice_transport] { EXPECT_EQ("connected", ice_transport->state()); }));
+ ice_transport->addEventListener(EventTypeNames::statechange, event_listener);
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+
+ delegate->OnStateChanged(cricket::IceTransportState::STATE_COMPLETED);
+
+ RunUntilIdle();
+}
+
+// Test that receiving an OnStateChanged callback with the failed state updates
+// the RTCIceTransport state to 'failed' and fires a statechange event.
+TEST_F(RTCIceTransportTest, OnStateChangedFailedUpdatesStateAndFiresEvent) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> event_listener = CreateMockEventListener();
+ EXPECT_CALL(*event_listener, handleEvent(_, _))
+ .WillOnce(InvokeWithoutArgs(
+ [ice_transport] { EXPECT_EQ("failed", ice_transport->state()); }));
+ ice_transport->addEventListener(EventTypeNames::statechange, event_listener);
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+
+ delegate->OnStateChanged(cricket::IceTransportState::STATE_FAILED);
+
+ RunUntilIdle();
+}
+
+// Test that calling OnSelectedCandidatePairChanged the first time fires the
+// selectedcandidatepairchange event and sets the selected candidate pair.
+TEST_F(RTCIceTransportTest, InitialOnSelectedCandidatePairChangedFiresEvent) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> event_listener = CreateMockEventListener();
+ EXPECT_CALL(*event_listener, handleEvent(_, _))
+ .WillOnce(InvokeWithoutArgs([ice_transport] {
+ base::Optional<RTCIceCandidatePair> selected_candidate_pair;
+ ice_transport->getSelectedCandidatePair(selected_candidate_pair);
+ ASSERT_TRUE(selected_candidate_pair);
+ EXPECT_EQ(ice_transport->getLocalCandidates()[0]->candidate(),
+ selected_candidate_pair->local()->candidate());
+ EXPECT_EQ(ice_transport->getRemoteCandidates()[0]->candidate(),
+ selected_candidate_pair->remote()->candidate());
+ }));
+ ice_transport->addEventListener(EventTypeNames::selectedcandidatepairchange,
+ event_listener);
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+ delegate->OnSelectedCandidatePairChanged(
+ std::make_pair(CricketCandidateFromString(kLocalIceCandidateStr1),
+ CricketCandidateFromString(kRemoteIceCandidateStr1)));
+
+ RunUntilIdle();
+}
+
+// Test that calling OnSelectedCandidatePairChanged with a different remote
+// candidate fires the event and updates the selected candidate pair.
+TEST_F(RTCIceTransportTest,
+ OnSelectedCandidatePairChangedWithDifferentRemoteCandidateFiresEvent) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> event_listener = CreateMockEventListener();
+ EXPECT_CALL(*event_listener, handleEvent(_, _))
+ .WillOnce(DoDefault()) // First event is already tested above.
+ .WillOnce(InvokeWithoutArgs([ice_transport] {
+ base::Optional<RTCIceCandidatePair> selected_candidate_pair;
+ ice_transport->getSelectedCandidatePair(selected_candidate_pair);
+ ASSERT_TRUE(selected_candidate_pair);
+ EXPECT_EQ(ice_transport->getLocalCandidates()[0]->candidate(),
+ selected_candidate_pair->local()->candidate());
+ EXPECT_EQ(ice_transport->getRemoteCandidates()[1]->candidate(),
+ selected_candidate_pair->remote()->candidate());
+ }));
+ ice_transport->addEventListener(EventTypeNames::selectedcandidatepairchange,
+ event_listener);
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+
+ delegate->OnSelectedCandidatePairChanged(
+ std::make_pair(CricketCandidateFromString(kLocalIceCandidateStr1),
+ CricketCandidateFromString(kRemoteIceCandidateStr1)));
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr2),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnSelectedCandidatePairChanged(
+ std::make_pair(CricketCandidateFromString(kLocalIceCandidateStr1),
+ CricketCandidateFromString(kRemoteIceCandidateStr2)));
+
+ RunUntilIdle();
+}
+
+// Test that receiving an OnStateChange callback to the failed state once a
+// connection has been established clears the selected candidate pair without
+// firing the selectedcandidatepairchange event.
+TEST_F(RTCIceTransportTest,
+ OnStateChangeFailedAfterConnectedClearsSelectedCandidatePair) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> state_change_event_listener =
+ CreateMockEventListener();
+ EXPECT_CALL(*state_change_event_listener, handleEvent(_, _))
+ .WillOnce(DoDefault()) // First event is for 'connected'.
+ .WillOnce(InvokeWithoutArgs([ice_transport] {
+ EXPECT_EQ("failed", ice_transport->state());
+ base::Optional<RTCIceCandidatePair> selected_candidate_pair;
+ ice_transport->getSelectedCandidatePair(selected_candidate_pair);
+ EXPECT_EQ(base::nullopt, selected_candidate_pair);
+ }));
+ ice_transport->addEventListener(EventTypeNames::statechange,
+ state_change_event_listener);
+
+ Persistent<MockEventListener> selected_candidate_pair_change_event_listener =
+ CreateMockEventListener();
+ EXPECT_CALL(*selected_candidate_pair_change_event_listener, handleEvent(_, _))
+ .Times(1); // First event is for the connected pair.
+ ice_transport->addEventListener(
+ EventTypeNames::selectedcandidatepairchange,
+ selected_candidate_pair_change_event_listener);
+
+ // Establish the connection
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+ delegate->OnStateChanged(cricket::IceTransportState::STATE_COMPLETED);
+ delegate->OnSelectedCandidatePairChanged(
+ std::make_pair(CricketCandidateFromString(kLocalIceCandidateStr1),
+ CricketCandidateFromString(kRemoteIceCandidateStr1)));
+
+ // Transition to failed.
+ delegate->OnStateChanged(cricket::IceTransportState::STATE_FAILED);
+
+ RunUntilIdle();
+}
+
+// Test that receiving an OnSelectedCandidatePairChange callback after a remote
+// ICE restart still updates the selected candidate pair.
+TEST_F(RTCIceTransportTest,
+ RemoteIceRestartRaceWithSelectedCandidatePairChange) {
+ V8TestingScope scope;
+
+ IceTransportAdapter::Delegate* delegate = nullptr;
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, &delegate);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+ RunUntilIdle();
+ ASSERT_TRUE(delegate);
+
+ Persistent<MockEventListener> event_listener = CreateMockEventListener();
+ EXPECT_CALL(*event_listener, handleEvent(_, _))
+ .WillOnce(InvokeWithoutArgs([ice_transport] {
+ base::Optional<RTCIceCandidatePair> selected_candidate_pair;
+ ice_transport->getSelectedCandidatePair(selected_candidate_pair);
+ ASSERT_TRUE(selected_candidate_pair);
+ EXPECT_EQ(kLocalIceCandidateStr1,
+ selected_candidate_pair->local()->candidate());
+ EXPECT_EQ(kRemoteIceCandidateStr1,
+ selected_candidate_pair->remote()->candidate());
+ }));
+ ice_transport->addEventListener(EventTypeNames::selectedcandidatepairchange,
+ event_listener);
+
+ ice_transport->addRemoteCandidate(
+ RTCIceCandidateFromString(scope, kRemoteIceCandidateStr1),
+ ASSERT_NO_EXCEPTION);
+
+ // Changing remote ICE parameters indicate a remote ICE restart. This clears
+ // the stored list of remote candidates.
+ ice_transport->start(CreateRemoteRTCIceParameters2(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ // These callbacks are part of the previous generation but should still take
+ // effect.
+ delegate->OnCandidateGathered(
+ CricketCandidateFromString(kLocalIceCandidateStr1));
+ delegate->OnStateChanged(cricket::IceTransportState::STATE_COMPLETED);
+ delegate->OnSelectedCandidatePairChanged(
+ std::make_pair(CricketCandidateFromString(kLocalIceCandidateStr1),
+ CricketCandidateFromString(kRemoteIceCandidateStr1)));
+
+ RunUntilIdle();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h
new file mode 100644
index 00000000000..9e2d7c1f91f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_TEST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_TEST_H_
+
+#include "base/test/test_simple_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_ice_transport_adapter.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
+
+namespace blink {
+
+class MockEventListener final : public EventListener {
+ public:
+ MockEventListener() : EventListener(ListenerType::kCPPEventListenerType) {}
+
+ bool operator==(const EventListener& other) const final {
+ return this == &other;
+ }
+
+ MOCK_METHOD2(handleEvent, void(ExecutionContext*, Event*));
+};
+
+class RTCIceTransportTest : public testing::Test {
+ public:
+ static RTCIceParameters CreateRemoteRTCIceParameters1();
+
+ RTCIceTransportTest();
+ ~RTCIceTransportTest() override;
+
+ // Run the main thread and worker thread until both are idle.
+ void RunUntilIdle();
+
+ // Construct a new RTCIceTrnasport with a default MockIceTransportAdapter.
+ RTCIceTransport* CreateIceTransport(V8TestingScope& scope);
+
+ // Construct a new RTCIceTransport with a mock IceTransportAdapter.
+ RTCIceTransport* CreateIceTransport(
+ V8TestingScope& scope,
+ IceTransportAdapter::Delegate** delegate_out);
+
+ // Construct a new RTCIceTransport with the given mock IceTransportAdapter.
+ // |delegate_out|, if non-null, will be populated once the IceTransportAdapter
+ // is constructed on the worker thread.
+ RTCIceTransport* CreateIceTransport(
+ V8TestingScope& scope,
+ std::unique_ptr<MockIceTransportAdapter> mock,
+ IceTransportAdapter::Delegate** delegate_out = nullptr);
+
+ // Use this method to construct a MockEventListener so that the expectations
+ // can be explicitly checked at the end of the test. Normally the expectations
+ // would be verified in the mock destructor, but since MockEventListener is
+ // garbage collected this may happen after the test has finished, improperly
+ // letting it pass.
+ MockEventListener* CreateMockEventListener();
+
+ private:
+ scoped_refptr<base::TestSimpleTaskRunner> main_thread_;
+ scoped_refptr<base::TestSimpleTaskRunner> worker_thread_;
+ std::vector<Persistent<MockEventListener>> mock_event_listeners_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_TEST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index f89532a99f3..1072ca64219 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -39,6 +39,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
@@ -113,7 +114,9 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
+#include "third_party/webrtc/api/jsep.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
+#include "third_party/webrtc/pc/sessiondescription.h"
namespace blink {
@@ -325,12 +328,14 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
web_configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
}
} else {
- if (!RuntimeEnabledFeatures::RTCUnifiedPlanByDefaultEnabled()) {
+ if (!base::FeatureList::IsEnabled(features::kRTCUnifiedPlanByDefault) &&
+ !RuntimeEnabledFeatures::RTCUnifiedPlanByDefaultEnabled()) {
// By default: The default SDP semantics is: "kPlanB".
web_configuration.sdp_semantics = webrtc::SdpSemantics::kPlanB;
} else {
// Override default SDP semantics to "kUnifiedPlan" with
- // RuntimeEnabled=RTCUnifiedPlanByDefault.
+ // --enable-features=RTCUnifiedPlanByDefault or with
+ // --enable-blink-features=RTCUnifiedPlanByDefault.
web_configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
}
}
@@ -549,7 +554,8 @@ RTCPeerConnection* RTCPeerConnection::Create(
}
RTCPeerConnection* peer_connection = new RTCPeerConnection(
- context, std::move(configuration), constraints, exception_state);
+ context, std::move(configuration), rtc_configuration.hasSdpSemantics(),
+ constraints, exception_state);
peer_connection->PauseIfNeeded();
if (exception_state.HadException())
return nullptr;
@@ -564,6 +570,7 @@ RTCPeerConnection* RTCPeerConnection::Create(
RTCPeerConnection::RTCPeerConnection(
ExecutionContext* context,
webrtc::PeerConnectionInterface::RTCConfiguration configuration,
+ bool sdp_semantics_specified,
WebMediaConstraints constraints,
ExceptionState& exception_state)
: PausableObject(context),
@@ -582,8 +589,9 @@ RTCPeerConnection::RTCPeerConnection(
stopped_(false),
closed_(false),
has_data_channels_(false),
- sdp_semantics_(configuration.sdp_semantics) {
- Document* document = ToDocument(GetExecutionContext());
+ sdp_semantics_(configuration.sdp_semantics),
+ sdp_semantics_specified_(sdp_semantics_specified) {
+ Document* document = To<Document>(GetExecutionContext());
InstanceCounters::IncrementCounter(
InstanceCounters::kRTCPeerConnectionCounter);
@@ -838,9 +846,47 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors(
return nullptr;
}
+bool RTCPeerConnection::ShouldShowComplexPlanBSdpWarning(
+ const RTCSessionDescriptionInit& session_description_init) const {
+ if (sdp_semantics_specified_)
+ return false;
+ if (!session_description_init.hasType() || !session_description_init.hasSdp())
+ return false;
+ std::unique_ptr<webrtc::SessionDescriptionInterface> session_description(
+ webrtc::CreateSessionDescription(
+ session_description_init.type().Utf8().data(),
+ session_description_init.sdp().Utf8().data(), nullptr));
+ if (!session_description)
+ return false;
+ size_t num_audio_mlines = 0u;
+ size_t num_video_mlines = 0u;
+ size_t num_audio_tracks = 0u;
+ size_t num_video_tracks = 0u;
+ for (const cricket::ContentInfo& content :
+ session_description->description()->contents()) {
+ cricket::MediaType media_type = content.media_description()->type();
+ size_t num_tracks = std::max(static_cast<size_t>(1u),
+ content.media_description()->streams().size());
+ if (media_type == cricket::MEDIA_TYPE_AUDIO) {
+ ++num_audio_mlines;
+ num_audio_tracks += num_tracks;
+ } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
+ ++num_video_mlines;
+ num_video_tracks += num_tracks;
+ }
+ }
+ return (num_audio_mlines == 1u && num_audio_tracks > 1u) ||
+ (num_video_mlines == 1u && num_video_tracks > 1u);
+}
+
ScriptPromise RTCPeerConnection::setLocalDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit& session_description_init) {
+ if (ShouldShowComplexPlanBSdpWarning(session_description_init)) {
+ Deprecation::CountDeprecation(
+ GetExecutionContext(),
+ WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics);
+ }
String sdp;
DOMException* exception = checkSdpForStateErrors(
ExecutionContext::From(script_state), session_description_init, &sdp);
@@ -861,6 +907,11 @@ ScriptPromise RTCPeerConnection::setLocalDescription(
const RTCSessionDescriptionInit& session_description_init,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) {
+ if (ShouldShowComplexPlanBSdpWarning(session_description_init)) {
+ Deprecation::CountDeprecation(
+ GetExecutionContext(),
+ WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics);
+ }
ExecutionContext* context = ExecutionContext::From(script_state);
if (success_callback && error_callback) {
UseCounter::Count(
@@ -926,6 +977,11 @@ RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() {
ScriptPromise RTCPeerConnection::setRemoteDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit& session_description_init) {
+ if (ShouldShowComplexPlanBSdpWarning(session_description_init)) {
+ Deprecation::CountDeprecation(
+ GetExecutionContext(),
+ WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics);
+ }
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
return ScriptPromise::RejectWithDOMException(
@@ -948,6 +1004,11 @@ ScriptPromise RTCPeerConnection::setRemoteDescription(
const RTCSessionDescriptionInit& session_description_init,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) {
+ if (ShouldShowComplexPlanBSdpWarning(session_description_init)) {
+ Deprecation::CountDeprecation(
+ GetExecutionContext(),
+ WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics);
+ }
ExecutionContext* context = ExecutionContext::From(script_state);
if (success_callback && error_callback) {
UseCounter::Count(
@@ -1928,6 +1989,13 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver(
if (receiver_it == rtp_receivers_.end()) {
// Create new receiver.
receiver = new RTCRtpReceiver(std::move(web_receiver), track, {});
+ // Receiving tracks should be muted by default. SetReadyState() propagates
+ // the related state changes to ensure it is muted on all layers. It also
+ // fires events - which is not desired - but because they fire synchronously
+ // there are no listeners to detect this so this is indistinguishable from
+ // having constructed the track in an already muted state.
+ receiver->track()->Component()->Source()->SetReadyState(
+ MediaStreamSource::kReadyStateMuted);
rtp_receivers_.push_back(receiver);
} else {
// Update existing receiver is a no-op.
@@ -2193,6 +2261,7 @@ void RTCPeerConnection::DidModifyTransceivers(
remove_list;
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>> add_list;
HeapVector<Member<RTCRtpTransceiver>> track_events;
+ MediaStreamVector previous_streams = getRemoteStreams();
for (auto& web_transceiver : web_transceivers) {
auto* it = FindTransceiver(*web_transceiver);
bool previously_had_recv =
@@ -2212,11 +2281,23 @@ void RTCPeerConnection::DidModifyTransceivers(
ProcessRemovalOfRemoteTrack(transceiver, &remove_list, &mute_tracks);
}
}
+ MediaStreamVector current_streams = getRemoteStreams();
for (auto& track : mute_tracks) {
+ // Mute the track. Fires "track.onmute" synchronously.
track->Component()->Source()->SetReadyState(
MediaStreamSource::kReadyStateMuted);
}
+ // Remove/add tracks to streams, this fires "stream.onremovetrack" and
+ // "stream.onaddtrack" asynchronously (delayed with ScheduleDispatchEvent()).
+ // This means that the streams will be updated immediately, but the
+ // corresponding events will fire after "pc.ontrack".
+ // TODO(https://crbug.com/788558): These should probably also fire
+ // synchronously (before "pc.ontrack"). The webrtc-pc spec references the
+ // mediacapture-streams spec for adding and removing tracks to streams, which
+ // adds/removes and fires synchronously, but it says to do this in a queued
+ // task, which would lead to unexpected behavior: the streams would be empty
+ // at "pc.ontrack".
for (auto& pair : remove_list) {
auto& stream = pair.first;
auto& track = pair.second;
@@ -2232,10 +2313,34 @@ void RTCPeerConnection::DidModifyTransceivers(
}
}
+ // Legacy APIs: "pc.onaddstream" and "pc.onremovestream".
+ for (const auto& current_stream : current_streams) {
+ if (!previous_streams.Contains(current_stream)) {
+ ScheduleDispatchEvent(
+ MediaStreamEvent::Create(EventTypeNames::addstream, current_stream));
+ }
+ }
+ for (const auto& previous_stream : previous_streams) {
+ if (!current_streams.Contains(previous_stream)) {
+ ScheduleDispatchEvent(MediaStreamEvent::Create(
+ EventTypeNames::removestream, previous_stream));
+ }
+ }
+
+ // Fire "pc.ontrack" synchronously.
for (auto& transceiver : track_events) {
- ScheduleDispatchEvent(new RTCTrackEvent(
+ auto* track_event = new RTCTrackEvent(
transceiver->receiver(), transceiver->receiver()->track(),
- transceiver->receiver()->streams(), transceiver));
+ transceiver->receiver()->streams(), transceiver);
+ DispatchEvent(*track_event);
+ }
+
+ // Unmute "pc.ontrack" tracks. Fires "track.onunmute" synchronously.
+ // TODO(https://crbug.com/889487): The correct thing to do is to unmute in
+ // response to receiving RTP packets.
+ for (auto& transceiver : track_events) {
+ transceiver->receiver()->track()->Component()->Source()->SetReadyState(
+ MediaStreamSource::kReadyStateLive);
}
}
@@ -2321,7 +2426,7 @@ void RTCPeerConnection::DidAddRemoteDataChannel(
}
void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) {
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
ukm::SourceId source_id = document->UkmSourceID();
ukm::builders::WebRTC_AddressHarvesting(source_id)
.SetUsagePattern(usage_pattern)
@@ -2446,7 +2551,7 @@ void RTCPeerConnection::CloseInternal() {
transceiver->OnPeerConnectionClosed();
}
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
HostsUsingFeatures::CountAnyWorld(
*document, HostsUsingFeatures::Feature::kRTCPeerConnectionUsed);
@@ -2483,7 +2588,7 @@ void RTCPeerConnection::DispatchScheduledEvent() {
}
void RTCPeerConnection::RecordRapporMetrics() {
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
for (const auto& component : tracks_.Keys()) {
switch (component->Source()->GetType()) {
case MediaStreamSource::kTypeAudio:
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index 49450d4fd8d..fc779f36c01 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -258,6 +258,18 @@ class MODULES_EXPORT RTCPeerConnection final
static int PeerConnectionCount();
static int PeerConnectionCountLimit();
+ // SLD/SRD helper method, public for testing.
+ // "Complex" Plan B SDP is SDP that is not compatible with Unified Plan, i.e.
+ // SDP that has multiple tracks listed under the same m= sections. We should
+ // show a deprecation warning when setLocalDescription() or
+ // setRemoteDescription() is called and:
+ // - The SDP is complex Plan B SDP.
+ // - sdpSemantics was not specified at RTCPeerConnection construction.
+ // Such calls would normally succeed, but as soon as the default switches to
+ // Unified Plan they would fail. This decides whether to show deprecation for
+ // WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics.
+ bool ShouldShowComplexPlanBSdpWarning(const RTCSessionDescriptionInit&) const;
+
void Trace(blink::Visitor*) override;
private:
@@ -288,6 +300,7 @@ class MODULES_EXPORT RTCPeerConnection final
RTCPeerConnection(ExecutionContext*,
webrtc::PeerConnectionInterface::RTCConfiguration,
+ bool sdp_semantics_specified,
WebMediaConstraints,
ExceptionState&);
void Dispose();
@@ -442,6 +455,8 @@ class MODULES_EXPORT RTCPeerConnection final
// "kUnifiedPlan", if constructed with "kDefault" it is translated to one or
// the other.
webrtc::SdpSemantics sdp_semantics_;
+ // Whether sdpSemantics was specified at construction.
+ bool sdp_semantics_specified_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
index d3c5e40b2ca..bdedd7d9cc0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
@@ -32,7 +32,7 @@ namespace blink {
class RTCIceCandidate;
class RTCPeerConnectionIceEventInit;
-class RTCPeerConnectionIceEvent final : public Event {
+class MODULES_EXPORT RTCPeerConnectionIceEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
index cdef1438738..a20d8fa8d5c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc
@@ -19,16 +19,352 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h"
namespace blink {
+static const char* kOfferSdpUnifiedPlanSingleAudioSingleVideo =
+ "v=0\r\n"
+ "o=- 6676943034916303038 2 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE 0 1\r\n"
+ "a=msid-semantic: WMS\r\n"
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 "
+ "126\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:pKAt\r\n"
+ "a=ice-pwd:bDmIGcCbVl+VkMymNfwdE/Mv\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "F2:D4:95:C5:FC:98:F2:7E:6F:6C:46:BF:5E:05:00:56:4F:A9:BC:4B:1E:56:98:C1:"
+ "68:BF:5E:7D:01:A3:EC:93\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:0\r\n"
+ "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
+ "a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n"
+ "a=sendrecv\r\n"
+ "a=msid:- 36f80301-b634-4c5a-a03b-d1ad79997531\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtpmap:111 opus/48000/2\r\n"
+ "a=rtcp-fb:111 transport-cc\r\n"
+ "a=fmtp:111 minptime=10;useinbandfec=1\r\n"
+ "a=rtpmap:103 ISAC/16000\r\n"
+ "a=rtpmap:104 ISAC/32000\r\n"
+ "a=rtpmap:9 G722/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:106 CN/32000\r\n"
+ "a=rtpmap:105 CN/16000\r\n"
+ "a=rtpmap:13 CN/8000\r\n"
+ "a=rtpmap:110 telephone-event/48000\r\n"
+ "a=rtpmap:112 telephone-event/32000\r\n"
+ "a=rtpmap:113 telephone-event/16000\r\n"
+ "a=rtpmap:126 telephone-event/8000\r\n"
+ "a=ssrc:4264546776 cname:GkUsSfx+DbDplYYT\r\n"
+ "a=ssrc:4264546776 msid: 36f80301-b634-4c5a-a03b-d1ad79997531\r\n"
+ "a=ssrc:4264546776 mslabel:\r\n"
+ "a=ssrc:4264546776 label:36f80301-b634-4c5a-a03b-d1ad79997531\r\n"
+ "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:pKAt\r\n"
+ "a=ice-pwd:bDmIGcCbVl+VkMymNfwdE/Mv\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "F2:D4:95:C5:FC:98:F2:7E:6F:6C:46:BF:5E:05:00:56:4F:A9:BC:4B:1E:56:98:C1:"
+ "68:BF:5E:7D:01:A3:EC:93\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:1\r\n"
+ "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n"
+ "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n"
+ "a=extmap:4 urn:3gpp:video-orientation\r\n"
+ "a=extmap:5 "
+ "http://www.ietf.org/id/"
+ "draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n"
+ "a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n"
+ "a=extmap:7 "
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n"
+ "a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n"
+ "a=extmap:10 "
+ "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\n"
+ "a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n"
+ "a=sendrecv\r\n"
+ "a=msid:- 0db71b61-c1ae-4741-bcce-320a254244f3\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtcp-rsize\r\n"
+ "a=rtpmap:96 VP8/90000\r\n"
+ "a=rtcp-fb:96 goog-remb\r\n"
+ "a=rtcp-fb:96 transport-cc\r\n"
+ "a=rtcp-fb:96 ccm fir\r\n"
+ "a=rtcp-fb:96 nack\r\n"
+ "a=rtcp-fb:96 nack pli\r\n"
+ "a=rtpmap:97 rtx/90000\r\n"
+ "a=fmtp:97 apt=96\r\n"
+ "a=rtpmap:98 VP9/90000\r\n"
+ "a=rtcp-fb:98 goog-remb\r\n"
+ "a=rtcp-fb:98 transport-cc\r\n"
+ "a=rtcp-fb:98 ccm fir\r\n"
+ "a=rtcp-fb:98 nack\r\n"
+ "a=rtcp-fb:98 nack pli\r\n"
+ "a=fmtp:98 x-google-profile-id=0\r\n"
+ "a=rtpmap:99 rtx/90000\r\n"
+ "a=fmtp:99 apt=98\r\n"
+ "a=rtpmap:100 red/90000\r\n"
+ "a=rtpmap:101 rtx/90000\r\n"
+ "a=fmtp:101 apt=100\r\n"
+ "a=rtpmap:102 ulpfec/90000\r\n"
+ "a=ssrc-group:FID 680673332 1566706172\r\n"
+ "a=ssrc:680673332 cname:GkUsSfx+DbDplYYT\r\n"
+ "a=ssrc:680673332 msid: 0db71b61-c1ae-4741-bcce-320a254244f3\r\n"
+ "a=ssrc:680673332 mslabel:\r\n"
+ "a=ssrc:680673332 label:0db71b61-c1ae-4741-bcce-320a254244f3\r\n"
+ "a=ssrc:1566706172 cname:GkUsSfx+DbDplYYT\r\n"
+ "a=ssrc:1566706172 msid: 0db71b61-c1ae-4741-bcce-320a254244f3\r\n"
+ "a=ssrc:1566706172 mslabel:\r\n"
+ "a=ssrc:1566706172 label:0db71b61-c1ae-4741-bcce-320a254244f3\r\n";
+
+static const char* kOfferSdpUnifiedPlanMultipleAudioTracks =
+ "v=0\r\n"
+ "o=- 1821816752660535838 2 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE 0 1\r\n"
+ "a=msid-semantic: WMS\r\n"
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 "
+ "126\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:rbEc\r\n"
+ "a=ice-pwd:vmDec3+MrTigDESzNiDuWBnD\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "05:9B:0A:BC:B3:E1:B9:5C:A6:78:96:23:00:0F:96:71:7B:B0:3E:37:87:1D:3A:62:"
+ "5E:00:A5:27:22:BB:26:5D\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:0\r\n"
+ "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
+ "a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n"
+ "a=sendrecv\r\n"
+ "a=msid:- adcd8158-3ad7-4a1f-ac87-8711db959fe8\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtpmap:111 opus/48000/2\r\n"
+ "a=rtcp-fb:111 transport-cc\r\n"
+ "a=fmtp:111 minptime=10;useinbandfec=1\r\n"
+ "a=rtpmap:103 ISAC/16000\r\n"
+ "a=rtpmap:104 ISAC/32000\r\n"
+ "a=rtpmap:9 G722/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:106 CN/32000\r\n"
+ "a=rtpmap:105 CN/16000\r\n"
+ "a=rtpmap:13 CN/8000\r\n"
+ "a=rtpmap:110 telephone-event/48000\r\n"
+ "a=rtpmap:112 telephone-event/32000\r\n"
+ "a=rtpmap:113 telephone-event/16000\r\n"
+ "a=rtpmap:126 telephone-event/8000\r\n"
+ "a=ssrc:2988156579 cname:gr88KGUzymBvrIaJ\r\n"
+ "a=ssrc:2988156579 msid: adcd8158-3ad7-4a1f-ac87-8711db959fe8\r\n"
+ "a=ssrc:2988156579 mslabel:\r\n"
+ "a=ssrc:2988156579 label:adcd8158-3ad7-4a1f-ac87-8711db959fe8\r\n"
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 "
+ "126\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:rbEc\r\n"
+ "a=ice-pwd:vmDec3+MrTigDESzNiDuWBnD\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "05:9B:0A:BC:B3:E1:B9:5C:A6:78:96:23:00:0F:96:71:7B:B0:3E:37:87:1D:3A:62:"
+ "5E:00:A5:27:22:BB:26:5D\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:1\r\n"
+ "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
+ "a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid\r\n"
+ "a=sendrecv\r\n"
+ "a=msid:- b5f69d2c-e753-4eb5-a302-d41ee75f9fcb\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtpmap:111 opus/48000/2\r\n"
+ "a=rtcp-fb:111 transport-cc\r\n"
+ "a=fmtp:111 minptime=10;useinbandfec=1\r\n"
+ "a=rtpmap:103 ISAC/16000\r\n"
+ "a=rtpmap:104 ISAC/32000\r\n"
+ "a=rtpmap:9 G722/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:106 CN/32000\r\n"
+ "a=rtpmap:105 CN/16000\r\n"
+ "a=rtpmap:13 CN/8000\r\n"
+ "a=rtpmap:110 telephone-event/48000\r\n"
+ "a=rtpmap:112 telephone-event/32000\r\n"
+ "a=rtpmap:113 telephone-event/16000\r\n"
+ "a=rtpmap:126 telephone-event/8000\r\n"
+ "a=ssrc:2562757057 cname:gr88KGUzymBvrIaJ\r\n"
+ "a=ssrc:2562757057 msid: b5f69d2c-e753-4eb5-a302-d41ee75f9fcb\r\n"
+ "a=ssrc:2562757057 mslabel:\r\n"
+ "a=ssrc:2562757057 label:b5f69d2c-e753-4eb5-a302-d41ee75f9fcb\r\n";
+
+static const char* kOfferSdpPlanBSingleAudioSingleVideo =
+ "v=0\r\n"
+ "o=- 267029810971159627 2 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE audio video\r\n"
+ "a=msid-semantic: WMS 655e92b8-9130-44d8-a188-f5f4633d1a8d "
+ "b15218e5-f921-4988-9e1f-6e50ecbd24c2\r\n"
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 "
+ "126\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:ErlQ\r\n"
+ "a=ice-pwd:VCnwY8XlD9EX4gpcOHRhU0HV\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "AC:30:90:F9:3B:CB:9A:0D:C6:FB:F3:D6:D6:97:4F:40:A2:B9:5E:4D:F5:32:DC:A7:"
+ "B0:3A:33:82:C8:67:FF:7A\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:audio\r\n"
+ "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
+ "a=sendrecv\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtpmap:111 opus/48000/2\r\n"
+ "a=rtcp-fb:111 transport-cc\r\n"
+ "a=fmtp:111 minptime=10;useinbandfec=1\r\n"
+ "a=rtpmap:103 ISAC/16000\r\n"
+ "a=rtpmap:104 ISAC/32000\r\n"
+ "a=rtpmap:9 G722/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:106 CN/32000\r\n"
+ "a=rtpmap:105 CN/16000\r\n"
+ "a=rtpmap:13 CN/8000\r\n"
+ "a=rtpmap:110 telephone-event/48000\r\n"
+ "a=rtpmap:112 telephone-event/32000\r\n"
+ "a=rtpmap:113 telephone-event/16000\r\n"
+ "a=rtpmap:126 telephone-event/8000\r\n"
+ "a=ssrc:1670492497 cname:rNEKgm1NFupmwR4x\r\n"
+ "a=ssrc:1670492497 msid:b15218e5-f921-4988-9e1f-6e50ecbd24c2 "
+ "089fd06c-73e4-4720-a6dc-e182eeaeced7\r\n"
+ "a=ssrc:1670492497 mslabel:b15218e5-f921-4988-9e1f-6e50ecbd24c2\r\n"
+ "a=ssrc:1670492497 label:089fd06c-73e4-4720-a6dc-e182eeaeced7\r\n"
+ "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:ErlQ\r\n"
+ "a=ice-pwd:VCnwY8XlD9EX4gpcOHRhU0HV\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "AC:30:90:F9:3B:CB:9A:0D:C6:FB:F3:D6:D6:97:4F:40:A2:B9:5E:4D:F5:32:DC:A7:"
+ "B0:3A:33:82:C8:67:FF:7A\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:video\r\n"
+ "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n"
+ "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n"
+ "a=extmap:4 urn:3gpp:video-orientation\r\n"
+ "a=extmap:5 "
+ "http://www.ietf.org/id/"
+ "draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n"
+ "a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n"
+ "a=extmap:7 "
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n"
+ "a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n"
+ "a=extmap:10 "
+ "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07\r\n"
+ "a=sendrecv\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtcp-rsize\r\n"
+ "a=rtpmap:96 VP8/90000\r\n"
+ "a=rtcp-fb:96 goog-remb\r\n"
+ "a=rtcp-fb:96 transport-cc\r\n"
+ "a=rtcp-fb:96 ccm fir\r\n"
+ "a=rtcp-fb:96 nack\r\n"
+ "a=rtcp-fb:96 nack pli\r\n"
+ "a=rtpmap:97 rtx/90000\r\n"
+ "a=fmtp:97 apt=96\r\n"
+ "a=rtpmap:98 VP9/90000\r\n"
+ "a=rtcp-fb:98 goog-remb\r\n"
+ "a=rtcp-fb:98 transport-cc\r\n"
+ "a=rtcp-fb:98 ccm fir\r\n"
+ "a=rtcp-fb:98 nack\r\n"
+ "a=rtcp-fb:98 nack pli\r\n"
+ "a=fmtp:98 x-google-profile-id=0\r\n"
+ "a=rtpmap:99 rtx/90000\r\n"
+ "a=fmtp:99 apt=98\r\n"
+ "a=rtpmap:100 red/90000\r\n"
+ "a=rtpmap:101 rtx/90000\r\n"
+ "a=fmtp:101 apt=100\r\n"
+ "a=rtpmap:102 ulpfec/90000\r\n"
+ "a=ssrc-group:FID 3263949794 2166305097\r\n"
+ "a=ssrc:3263949794 cname:rNEKgm1NFupmwR4x\r\n"
+ "a=ssrc:3263949794 msid:655e92b8-9130-44d8-a188-f5f4633d1a8d "
+ "6391e0e8-ac1e-42c2-844c-a7299758db6a\r\n"
+ "a=ssrc:3263949794 mslabel:655e92b8-9130-44d8-a188-f5f4633d1a8d\r\n"
+ "a=ssrc:3263949794 label:6391e0e8-ac1e-42c2-844c-a7299758db6a\r\n"
+ "a=ssrc:2166305097 cname:rNEKgm1NFupmwR4x\r\n"
+ "a=ssrc:2166305097 msid:655e92b8-9130-44d8-a188-f5f4633d1a8d "
+ "6391e0e8-ac1e-42c2-844c-a7299758db6a\r\n"
+ "a=ssrc:2166305097 mslabel:655e92b8-9130-44d8-a188-f5f4633d1a8d\r\n"
+ "a=ssrc:2166305097 label:6391e0e8-ac1e-42c2-844c-a7299758db6a\r\n";
+
+static const char* kOfferSdpPlanBMultipleAudioTracks =
+ "v=0\r\n"
+ "o=- 6228437149521864740 2 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE audio\r\n"
+ "a=msid-semantic: WMS 46f8615e-7599-49f3-9a45-3cf0faf58614 "
+ "e01b7c23-2b77-4e09-bee7-4b9140e49647\r\n"
+ "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 "
+ "126\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp:9 IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:Nzla\r\n"
+ "a=ice-pwd:PL1APGM2pr773UoUOsj8jzBI\r\n"
+ "a=ice-options:trickle\r\n"
+ "a=fingerprint:sha-256 "
+ "DF:8F:89:33:68:AB:55:26:4E:81:CF:95:8C:71:B7:89:45:E7:05:7A:5D:A8:CF:BF:"
+ "60:AA:C7:42:F2:85:23:1D\r\n"
+ "a=setup:actpass\r\n"
+ "a=mid:audio\r\n"
+ "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
+ "a=sendrecv\r\n"
+ "a=rtcp-mux\r\n"
+ "a=rtpmap:111 opus/48000/2\r\n"
+ "a=rtcp-fb:111 transport-cc\r\n"
+ "a=fmtp:111 minptime=10;useinbandfec=1\r\n"
+ "a=rtpmap:103 ISAC/16000\r\n"
+ "a=rtpmap:104 ISAC/32000\r\n"
+ "a=rtpmap:9 G722/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:106 CN/32000\r\n"
+ "a=rtpmap:105 CN/16000\r\n"
+ "a=rtpmap:13 CN/8000\r\n"
+ "a=rtpmap:110 telephone-event/48000\r\n"
+ "a=rtpmap:112 telephone-event/32000\r\n"
+ "a=rtpmap:113 telephone-event/16000\r\n"
+ "a=rtpmap:126 telephone-event/8000\r\n"
+ "a=ssrc:2716812081 cname:0QgfsHYGSuZjeg5/\r\n"
+ "a=ssrc:2716812081 msid:e01b7c23-2b77-4e09-bee7-4b9140e49647 "
+ "d73d8a47-3d3f-408f-a2ce-2270eb44ffc5\r\n"
+ "a=ssrc:2716812081 mslabel:e01b7c23-2b77-4e09-bee7-4b9140e49647\r\n"
+ "a=ssrc:2716812081 label:d73d8a47-3d3f-408f-a2ce-2270eb44ffc5\r\n"
+ "a=ssrc:4092260337 cname:0QgfsHYGSuZjeg5/\r\n"
+ "a=ssrc:4092260337 msid:46f8615e-7599-49f3-9a45-3cf0faf58614 "
+ "6b5f436e-f85d-40a1-83e4-acec63ca4b82\r\n"
+ "a=ssrc:4092260337 mslabel:46f8615e-7599-49f3-9a45-3cf0faf58614\r\n"
+ "a=ssrc:4092260337 label:6b5f436e-f85d-40a1-83e4-acec63ca4b82\r\n";
+
class RTCPeerConnectionTest : public testing::Test {
public:
- RTCPeerConnection* CreatePC(V8TestingScope& scope) {
+ RTCPeerConnection* CreatePC(V8TestingScope& scope,
+ const String& sdpSemantics = String()) {
RTCConfiguration config;
+ config.setSdpSemantics(sdpSemantics);
RTCIceServer ice_server;
ice_server.setURL("stun:fake.stun.url");
HeapVector<RTCIceServer> ice_servers;
@@ -236,4 +572,78 @@ TEST_F(RTCPeerConnectionTest, GetTrackRemoveStreamAndGCWithPersistentStream) {
EXPECT_FALSE(pc->GetTrack(track_component));
}
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownWhenPlanBSpecified) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope, "plan-b");
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ // It doesn't matter the SDP, never show a warning if sdpSemantics was
+ // specified at construction.
+ sdp.setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpPlanBMultipleAudioTracks);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownWhenUnifiedPlanSpecified) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope, "unified-plan");
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ // It doesn't matter the SDP, never show a warning if sdpSemantics was
+ // specified at construction.
+ sdp.setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpPlanBMultipleAudioTracks);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownWhenInvalidSdp) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope);
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ sdp.setSdp("invalid sdp");
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownForSingleTracks) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope);
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ // Neither Unified Plan or Plan B SDP should result in a warning if only a
+ // single track per m= section is used.
+ sdp.setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+ sdp.setSdp(kOfferSdpPlanBSingleAudioSingleVideo);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningShownForComplexPlanB) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope);
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ sdp.setSdp(kOfferSdpPlanBMultipleAudioTracks);
+ ASSERT_TRUE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
+TEST_F(RTCPeerConnectionTest, PlanBSdpWarningNotShownForComplexUnifiedPlan) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc = CreatePC(scope);
+ RTCSessionDescriptionInit sdp;
+ sdp.setType("offer");
+ sdp.setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks);
+ ASSERT_FALSE(pc->ShouldShowComplexPlanBSdpWarning(sdp));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
index ef0cc254f68..66f32031b94 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
@@ -3,13 +3,20 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
namespace blink {
-RTCQuicStream::RTCQuicStream(RTCQuicTransport* transport)
- : transport_(transport) {
+RTCQuicStream::RTCQuicStream(ExecutionContext* context,
+ RTCQuicTransport* transport,
+ QuicStreamProxy* stream_proxy)
+ : EventTargetWithInlineData(),
+ ContextClient(context),
+ transport_(transport),
+ proxy_(stream_proxy) {
DCHECK(transport_);
+ DCHECK(proxy_);
}
RTCQuicStream::~RTCQuicStream() = default;
@@ -42,13 +49,75 @@ uint32_t RTCQuicStream::writeBufferedAmount() const {
return write_buffered_amount_;
}
+void RTCQuicStream::finish() {
+ if (!writeable_) {
+ return;
+ }
+ proxy_->Finish();
+ writeable_ = false;
+ if (readable_) {
+ DCHECK_EQ(state_, RTCQuicStreamState::kOpen);
+ state_ = RTCQuicStreamState::kClosing;
+ } else {
+ DCHECK_EQ(state_, RTCQuicStreamState::kClosing);
+ Close();
+ }
+}
+
+void RTCQuicStream::reset() {
+ if (IsClosed()) {
+ return;
+ }
+ proxy_->Reset();
+ writeable_ = false;
+ readable_ = false;
+ Close();
+}
+
void RTCQuicStream::Stop() {
+ readable_ = false;
+ writeable_ = false;
state_ = RTCQuicStreamState::kClosed;
+ proxy_ = nullptr;
+}
+
+void RTCQuicStream::Close() {
+ Stop();
+ transport_->RemoveStream(this);
+}
+
+void RTCQuicStream::OnRemoteReset() {
+ DCHECK_NE(state_, RTCQuicStreamState::kClosed);
+ Close();
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+void RTCQuicStream::OnRemoteFinish() {
+ DCHECK_NE(state_, RTCQuicStreamState::kClosed);
+ DCHECK(readable_);
+ readable_ = false;
+ if (writeable_) {
+ DCHECK_EQ(state_, RTCQuicStreamState::kOpen);
+ state_ = RTCQuicStreamState::kClosing;
+ } else {
+ DCHECK_EQ(state_, RTCQuicStreamState::kClosing);
+ Close();
+ }
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+const AtomicString& RTCQuicStream::InterfaceName() const {
+ return EventTargetNames::RTCQuicStream;
+}
+
+ExecutionContext* RTCQuicStream::GetExecutionContext() const {
+ return ContextClient::GetExecutionContext();
}
void RTCQuicStream::Trace(blink::Visitor* visitor) {
visitor->Trace(transport_);
- ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
+ ContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
index db56e123ab7..b2952b2cffb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
@@ -5,8 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
namespace blink {
@@ -14,29 +16,54 @@ class RTCQuicTransport;
enum class RTCQuicStreamState { kNew, kOpening, kOpen, kClosing, kClosed };
-class MODULES_EXPORT RTCQuicStream final : public ScriptWrappable {
+class MODULES_EXPORT RTCQuicStream final : public EventTargetWithInlineData,
+ public ContextClient,
+ public QuicStreamProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
public:
- RTCQuicStream(RTCQuicTransport* transport);
+ RTCQuicStream(ExecutionContext* context,
+ RTCQuicTransport* transport,
+ QuicStreamProxy* stream_proxy);
~RTCQuicStream() override;
+ // Called from the RTCQuicTransport when it is being stopped.
void Stop();
+ bool IsClosed() const { return state_ == RTCQuicStreamState::kClosed; }
// rtc_quic_stream.idl
RTCQuicTransport* transport() const;
String state() const;
uint32_t readBufferedAmount() const;
uint32_t writeBufferedAmount() const;
+ void finish();
+ void reset();
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
+
+ // EventTarget overrides.
+ const AtomicString& InterfaceName() const override;
+ ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
void Trace(blink::Visitor* visitor) override;
private:
+ // Closes the stream. This will change the state to kClosed and deregister it
+ // from the RTCQuicTransport. The QuicStreamProxy can no longer be used after
+ // this point.
+ void Close();
+
+ // QuicStreamProxy::Delegate overrides.
+ void OnRemoteReset() override;
+ void OnRemoteFinish() override;
+
Member<RTCQuicTransport> transport_;
- RTCQuicStreamState state_ = RTCQuicStreamState::kNew;
+ RTCQuicStreamState state_ = RTCQuicStreamState::kOpen;
+ bool readable_ = true;
+ bool writeable_ = true;
uint32_t read_buffered_amount_ = 0;
uint32_t write_buffered_amount_ = 0;
+ QuicStreamProxy* proxy_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl
index edc318407df..945d6b4af5d 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl
@@ -14,12 +14,15 @@ enum RTCQuicStreamState {
// https://w3c.github.io/webrtc-quic/#quicstream*
[
Exposed=Window,
- RuntimeEnabled=RTCQuicStream
-] interface RTCQuicStream {
+ RuntimeEnabled=RTCQuicTransport
+] interface RTCQuicStream : EventTarget {
readonly attribute RTCQuicTransport transport;
readonly attribute RTCQuicStreamState state;
readonly attribute unsigned long readBufferedAmount;
readonly attribute unsigned long writeBufferedAmount;
+ void finish();
+ void reset();
+ attribute EventHandler onstatechange;
// TODO(crbug.com/868068): Implement remaining methods, attributes, and events.
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc
new file mode 100644
index 00000000000..af4228d12f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc
@@ -0,0 +1,45 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.h"
+
+namespace blink {
+
+RTCQuicStreamEvent* RTCQuicStreamEvent::Create(RTCQuicStream* stream) {
+ return new RTCQuicStreamEvent(stream);
+}
+
+RTCQuicStreamEvent* RTCQuicStreamEvent::Create(
+ const AtomicString& type,
+ const RTCQuicStreamEventInit& initializer) {
+ return new RTCQuicStreamEvent(type, initializer);
+}
+
+RTCQuicStreamEvent::RTCQuicStreamEvent(RTCQuicStream* stream)
+ : Event(EventTypeNames::quicstream, Bubbles::kNo, Cancelable::kNo),
+ stream_(stream) {}
+
+RTCQuicStreamEvent::RTCQuicStreamEvent(
+ const AtomicString& type,
+ const RTCQuicStreamEventInit& initializer)
+ : Event(type, initializer), stream_(initializer.stream()) {}
+
+RTCQuicStreamEvent::~RTCQuicStreamEvent() = default;
+
+RTCQuicStream* RTCQuicStreamEvent::stream() const {
+ return stream_.Get();
+}
+
+const AtomicString& RTCQuicStreamEvent::InterfaceName() const {
+ return EventNames::RTCQuicStreamEvent;
+}
+
+void RTCQuicStreamEvent::Trace(blink::Visitor* visitor) {
+ visitor->Trace(stream_);
+ Event::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h
new file mode 100644
index 00000000000..6e60d9a40ae
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
+
+#include "third_party/blink/renderer/modules/event_modules.h"
+
+namespace blink {
+
+class RTCQuicStream;
+class RTCQuicStreamEventInit;
+
+class RTCQuicStreamEvent final : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static RTCQuicStreamEvent* Create(RTCQuicStream* stream);
+ static RTCQuicStreamEvent* Create(const AtomicString& type,
+ const RTCQuicStreamEventInit& init);
+
+ ~RTCQuicStreamEvent() override;
+
+ // rtc_quic_stream_event.idl
+ RTCQuicStream* stream() const;
+
+ // Event overrides.
+ const AtomicString& InterfaceName() const override;
+
+ // For garbage collection.
+ void Trace(blink::Visitor*) override;
+
+ private:
+ RTCQuicStreamEvent(RTCQuicStream* stream);
+ RTCQuicStreamEvent(const AtomicString& type,
+ const RTCQuicStreamEventInit& init);
+
+ Member<RTCQuicStream> stream_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl
new file mode 100644
index 00000000000..ced237c75eb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl
@@ -0,0 +1,12 @@
+// 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.
+
+// https://w3c.github.io/webrtc-quic/#rtcquicstreamevent
+[
+ RuntimeEnabled=RTCQuicTransport,
+ Constructor(DOMString type, optional RTCQuicStreamEventInit eventInitDict),
+ Exposed=Window
+] interface RTCQuicStreamEvent : Event {
+ readonly attribute RTCQuicStream stream;
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.idl
new file mode 100644
index 00000000000..53e3bcd1218
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://w3c.github.io/webrtc-quic/#dom-rtcquicstreameventinit
+dictionary RTCQuicStreamEventInit : EventInit {
+ RTCQuicStream stream;
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
index 407a8bb249a..926ba270ffc 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -4,24 +4,91 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
+#include "net/third_party/quic/platform/impl/quic_chromium_clock.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
namespace blink {
+namespace {
+
+// This class wraps a P2PQuicTransportFactoryImpl but does not construct it
+// until CreateQuicTransport is called for the first time. This ensures that it
+// is executed on the WebRTC worker thread.
+class DefaultP2PQuicTransportFactory : public P2PQuicTransportFactory {
+ public:
+ explicit DefaultP2PQuicTransportFactory(
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread)
+ : host_thread_(std::move(host_thread)) {
+ DCHECK(host_thread_);
+ }
+
+ // P2PQuicTransportFactory overrides.
+ std::unique_ptr<P2PQuicTransport> CreateQuicTransport(
+ P2PQuicTransportConfig config) override {
+ DCHECK(host_thread_->RunsTasksInCurrentSequence());
+ return GetFactory()->CreateQuicTransport(std::move(config));
+ }
+
+ private:
+ P2PQuicTransportFactory* GetFactory() {
+ DCHECK(host_thread_->RunsTasksInCurrentSequence());
+ if (!factory_impl_) {
+ quic::QuicClock* clock = quic::QuicChromiumClock::GetInstance();
+ auto alarm_factory = std::make_unique<net::QuicChromiumAlarmFactory>(
+ host_thread_.get(), clock);
+ factory_impl_ = std::make_unique<P2PQuicTransportFactoryImpl>(
+ clock, std::move(alarm_factory));
+ }
+ return factory_impl_.get();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread_;
+ std::unique_ptr<P2PQuicTransportFactory> factory_impl_;
+};
+
+} // namespace
RTCQuicTransport* RTCQuicTransport::Create(
+ ExecutionContext* context,
RTCIceTransport* transport,
const HeapVector<Member<RTCCertificate>>& certificates,
ExceptionState& exception_state) {
+ return Create(context, transport, certificates, exception_state,
+ std::make_unique<DefaultP2PQuicTransportFactory>(
+ Platform::Current()->GetWebRtcWorkerThread()));
+}
+
+RTCQuicTransport* RTCQuicTransport::Create(
+ ExecutionContext* context,
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state,
+ std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory) {
+ DCHECK(context);
+ DCHECK(transport);
+ DCHECK(p2p_quic_transport_factory);
if (transport->IsClosed()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"Cannot construct an RTCQuicTransport with a closed RTCIceTransport.");
return nullptr;
}
+ if (transport->HasConsumer()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot construct an RTCQuicTransport "
+ "with an RTCIceTransport that already "
+ "has a connected RTCQuicTransport.");
+ return nullptr;
+ }
for (const auto& certificate : certificates) {
if (certificate->expires() < ConvertSecondsToDOMTimeStamp(CurrentTime())) {
exception_state.ThrowTypeError(
@@ -29,16 +96,38 @@ RTCQuicTransport* RTCQuicTransport::Create(
return nullptr;
}
}
- return new RTCQuicTransport(transport, certificates, exception_state);
+ return new RTCQuicTransport(context, transport, certificates, exception_state,
+ std::move(p2p_quic_transport_factory));
}
RTCQuicTransport::RTCQuicTransport(
+ ExecutionContext* context,
RTCIceTransport* transport,
const HeapVector<Member<RTCCertificate>>& certificates,
- ExceptionState& exception_state)
- : transport_(transport), certificates_(certificates) {}
+ ExceptionState& exception_state,
+ std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory)
+ : ContextLifecycleObserver(context),
+ transport_(transport),
+ certificates_(certificates),
+ p2p_quic_transport_factory_(std::move(p2p_quic_transport_factory)) {
+ transport->ConnectConsumer(this);
+}
+
+RTCQuicTransport::~RTCQuicTransport() {
+ DCHECK(!proxy_);
+}
-RTCQuicTransport::~RTCQuicTransport() = default;
+void RTCQuicTransport::Close(RTCQuicTransportState new_state) {
+ DCHECK(!IsClosed());
+ for (RTCQuicStream* stream : streams_) {
+ stream->Stop();
+ }
+ streams_.clear();
+ transport_->DisconnectConsumer(this);
+ proxy_.reset();
+ state_ = new_state;
+ DCHECK(IsClosed());
+}
RTCIceTransport* RTCQuicTransport::transport() const {
return transport_;
@@ -76,7 +165,7 @@ void RTCQuicTransport::getLocalParameters(RTCQuicParameters& result) const {
void RTCQuicTransport::getRemoteParameters(
base::Optional<RTCQuicParameters>& result) const {
- result = base::nullopt;
+ result = remote_parameters_;
}
const HeapVector<Member<RTCCertificate>>& RTCQuicTransport::getCertificates()
@@ -89,23 +178,131 @@ RTCQuicTransport::getRemoteCertificates() const {
return remote_certificates_;
}
+static quic::Perspective QuicPerspectiveFromIceRole(cricket::IceRole ice_role) {
+ switch (ice_role) {
+ case cricket::ICEROLE_CONTROLLED:
+ return quic::Perspective::IS_CLIENT;
+ case cricket::ICEROLE_CONTROLLING:
+ return quic::Perspective::IS_SERVER;
+ default:
+ NOTREACHED();
+ }
+ return quic::Perspective::IS_CLIENT;
+}
+
+void RTCQuicTransport::start(const RTCQuicParameters& remote_parameters,
+ ExceptionState& exception_state) {
+ if (RaiseExceptionIfClosed(exception_state)) {
+ return;
+ }
+ if (remote_parameters_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot start() multiple times.");
+ return;
+ }
+ remote_parameters_ = remote_parameters;
+ if (transport_->IsStarted()) {
+ StartConnection();
+ }
+}
+
+static std::unique_ptr<rtc::SSLFingerprint> RTCDtlsFingerprintToSSLFingerprint(
+ const RTCDtlsFingerprint& dtls_fingerprint) {
+ std::string algorithm = WebString(dtls_fingerprint.algorithm()).Utf8();
+ std::string value = WebString(dtls_fingerprint.value()).Utf8();
+ std::unique_ptr<rtc::SSLFingerprint> rtc_fingerprint(
+ rtc::SSLFingerprint::CreateFromRfc4572(algorithm, value));
+ DCHECK(rtc_fingerprint);
+ return rtc_fingerprint;
+}
+
+void RTCQuicTransport::StartConnection() {
+ DCHECK_EQ(state_, RTCQuicTransportState::kNew);
+ DCHECK(remote_parameters_);
+
+ state_ = RTCQuicTransportState::kConnecting;
+
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> rtc_certificates;
+ for (const auto& certificate : certificates_) {
+ rtc_certificates.push_back(certificate->Certificate());
+ }
+ IceTransportProxy* transport_proxy = transport_->ConnectConsumer(this);
+ proxy_.reset(new QuicTransportProxy(
+ this, transport_proxy, QuicPerspectiveFromIceRole(transport_->GetRole()),
+ rtc_certificates, std::move(p2p_quic_transport_factory_)));
+
+ std::vector<std::unique_ptr<rtc::SSLFingerprint>> rtc_fingerprints;
+ for (const RTCDtlsFingerprint& fingerprint :
+ remote_parameters_->fingerprints()) {
+ rtc_fingerprints.push_back(RTCDtlsFingerprintToSSLFingerprint(fingerprint));
+ }
+ proxy_->Start(std::move(rtc_fingerprints));
+}
+
+void RTCQuicTransport::OnTransportStarted() {
+ // The RTCIceTransport has now been started.
+ if (remote_parameters_) {
+ StartConnection();
+ }
+}
+
void RTCQuicTransport::stop() {
- for (RTCQuicStream* stream : streams_) {
- stream->Stop();
+ if (IsClosed()) {
+ return;
}
- streams_.clear();
- state_ = RTCQuicTransportState::kClosed;
+ if (proxy_) {
+ proxy_->Stop();
+ }
+ Close(RTCQuicTransportState::kClosed);
}
RTCQuicStream* RTCQuicTransport::createStream(ExceptionState& exception_state) {
- if (RaiseExceptionIfClosed(exception_state)) {
+ // TODO(github.com/w3c/webrtc-quic/issues/50): Maybe support createStream in
+ // the 'new' or 'connecting' states.
+ if (state_ != RTCQuicTransportState::kConnected) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "RTCQuicTransport.createStream() is only "
+ "valid in the 'connected' state.");
return nullptr;
}
- RTCQuicStream* stream = new RTCQuicStream(this);
+ return AddStream(proxy_->CreateStream());
+}
+
+RTCQuicStream* RTCQuicTransport::AddStream(QuicStreamProxy* stream_proxy) {
+ auto* stream = new RTCQuicStream(GetExecutionContext(), this, stream_proxy);
+ stream_proxy->set_delegate(stream);
streams_.insert(stream);
return stream;
}
+void RTCQuicTransport::RemoveStream(RTCQuicStream* stream) {
+ DCHECK(stream);
+ auto it = streams_.find(stream);
+ DCHECK(it != streams_.end());
+ streams_.erase(it);
+}
+
+void RTCQuicTransport::OnConnected() {
+ state_ = RTCQuicTransportState::kConnected;
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+void RTCQuicTransport::OnConnectionFailed(const std::string& error_details,
+ bool from_remote) {
+ Close(RTCQuicTransportState::kFailed);
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+void RTCQuicTransport::OnRemoteStopped() {
+ Close(RTCQuicTransportState::kClosed);
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+void RTCQuicTransport::OnStream(QuicStreamProxy* stream_proxy) {
+ RTCQuicStream* stream = AddStream(stream_proxy);
+ DispatchEvent(*RTCQuicStreamEvent::Create(stream));
+}
+
bool RTCQuicTransport::RaiseExceptionIfClosed(
ExceptionState& exception_state) const {
if (IsClosed()) {
@@ -117,12 +314,30 @@ bool RTCQuicTransport::RaiseExceptionIfClosed(
return false;
}
+const AtomicString& RTCQuicTransport::InterfaceName() const {
+ return EventTargetNames::RTCQuicTransport;
+}
+
+ExecutionContext* RTCQuicTransport::GetExecutionContext() const {
+ return ContextLifecycleObserver::GetExecutionContext();
+}
+
+void RTCQuicTransport::ContextDestroyed(ExecutionContext*) {
+ stop();
+}
+
+bool RTCQuicTransport::HasPendingActivity() const {
+ return static_cast<bool>(proxy_);
+}
+
void RTCQuicTransport::Trace(blink::Visitor* visitor) {
visitor->Trace(transport_);
visitor->Trace(certificates_);
visitor->Trace(remote_certificates_);
+ visitor->Trace(remote_parameters_);
visitor->Trace(streams_);
- ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
+ ContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
index 161dd63c873..d469d81ae28 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
@@ -5,8 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
+#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/modules/event_target_modules.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -14,8 +17,8 @@ class DOMArrayBuffer;
class ExceptionState;
class RTCCertificate;
class RTCIceTransport;
-class RTCQuicParameters;
class RTCQuicStream;
+class P2PQuicTransportFactory;
enum class RTCQuicTransportState {
kNew,
@@ -25,17 +28,32 @@ enum class RTCQuicTransportState {
kFailed
};
-class MODULES_EXPORT RTCQuicTransport final : public ScriptWrappable {
+class MODULES_EXPORT RTCQuicTransport final
+ : public EventTargetWithInlineData,
+ public ActiveScriptWrappable<RTCQuicTransport>,
+ public ContextLifecycleObserver,
+ public QuicTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(RTCQuicTransport);
public:
static RTCQuicTransport* Create(
+ ExecutionContext* context,
RTCIceTransport* transport,
const HeapVector<Member<RTCCertificate>>& certificates,
ExceptionState& exception_state);
+ static RTCQuicTransport* Create(
+ ExecutionContext* context,
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state,
+ std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory);
~RTCQuicTransport() override;
+ RTCQuicStream* AddStream(QuicStreamProxy* stream_proxy);
+ void RemoveStream(RTCQuicStream* stream);
+
// https://w3c.github.io/webrtc-quic/#quic-transport*
RTCIceTransport* transport() const;
String state() const;
@@ -43,24 +61,62 @@ class MODULES_EXPORT RTCQuicTransport final : public ScriptWrappable {
void getRemoteParameters(base::Optional<RTCQuicParameters>& result) const;
const HeapVector<Member<RTCCertificate>>& getCertificates() const;
const HeapVector<Member<DOMArrayBuffer>>& getRemoteCertificates() const;
+ void start(const RTCQuicParameters& remote_parameters,
+ ExceptionState& exception_state);
void stop();
RTCQuicStream* createStream(ExceptionState& exception_state);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(quicstream);
+
+ // Called by the RTCIceTransport when its start() method is called.
+ void OnTransportStarted();
+
+ // EventTarget overrides.
+ const AtomicString& InterfaceName() const override;
+ ExecutionContext* GetExecutionContext() const override;
+
+ // ContextLifecycleObserver overrides.
+ void ContextDestroyed(ExecutionContext*) override;
+
+ // ActiveScriptWrappable overrides.
+ bool HasPendingActivity() const override;
// For garbage collection.
void Trace(blink::Visitor* visitor) override;
private:
- RTCQuicTransport(RTCIceTransport* transport,
- const HeapVector<Member<RTCCertificate>>& certificates,
- ExceptionState& exception_state);
+ RTCQuicTransport(
+ ExecutionContext* context,
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state,
+ std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory);
+
+ // QuicTransportProxy::Delegate overrides;
+ void OnConnected() override;
+ void OnConnectionFailed(const std::string& error_details,
+ bool from_remote) override;
+ void OnRemoteStopped() override;
+ void OnStream(QuicStreamProxy* stream_proxy) override;
bool IsClosed() const { return state_ == RTCQuicTransportState::kClosed; }
bool RaiseExceptionIfClosed(ExceptionState& exception_state) const;
+ // Starts the underlying QUIC connection.
+ void StartConnection();
+
+ // Close all streams, delete the underlying QUIC transport, and transition to
+ // the given state, closed or failed.
+ void Close(RTCQuicTransportState new_state);
+
Member<RTCIceTransport> transport_;
RTCQuicTransportState state_ = RTCQuicTransportState::kNew;
HeapVector<Member<RTCCertificate>> certificates_;
HeapVector<Member<DOMArrayBuffer>> remote_certificates_;
+ base::Optional<RTCQuicParameters> remote_parameters_;
+ std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory_;
+ std::unique_ptr<QuicTransportProxy> proxy_;
HeapHashSet<Member<RTCQuicStream>> streams_;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
index df348136a76..ab25d010506 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
@@ -13,18 +13,23 @@ enum RTCQuicTransportState {
// https://w3c.github.io/webrtc-quic/#quic-transport*
[
+ ActiveScriptWrappable,
Constructor(RTCIceTransport transport, sequence<RTCCertificate> certificates),
+ ConstructorCallWith=ExecutionContext,
RaisesException=Constructor,
Exposed=Window,
RuntimeEnabled=RTCQuicTransport
-] interface RTCQuicTransport {
+] interface RTCQuicTransport : EventTarget {
readonly attribute RTCIceTransport transport;
readonly attribute RTCQuicTransportState state;
RTCQuicParameters getLocalParameters();
RTCQuicParameters? getRemoteParameters();
sequence<RTCCertificate> getCertificates();
sequence<ArrayBuffer> getRemoteCertificates();
+ [RaisesException] void start(RTCQuicParameters remoteParameters);
void stop();
- [RaisesException, RuntimeEnabled=RTCQuicStream] RTCQuicStream createStream();
- // TODO(crbug.com/868068): Implement remaining control methods + events.
+ [RaisesException] RTCQuicStream createStream();
+ attribute EventHandler onstatechange;
+ attribute EventHandler onerror;
+ attribute EventHandler onquicstream;
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
new file mode 100644
index 00000000000..e16b065df82
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
@@ -0,0 +1,235 @@
+// 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.
+
+// This file tests the RTCQuicTransport Blink bindings, QuicTransportProxy and
+// QuicTransportHost by mocking out the underlying P2PQuicTransport.
+// Everything is run on a single thread but with separate TestSimpleTaskRunners
+// for the main thread / worker thread.
+
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_packet_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
+#include "third_party/webrtc/rtc_base/rtccertificategenerator.h"
+
+namespace blink {
+namespace {
+
+using testing::_;
+using testing::Assign;
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::Mock;
+
+HeapVector<Member<RTCCertificate>> GenerateLocalRTCCertificates() {
+ HeapVector<Member<RTCCertificate>> certificates;
+ certificates.push_back(
+ new RTCCertificate(rtc::RTCCertificateGenerator::GenerateCertificate(
+ rtc::KeyParams::ECDSA(), absl::nullopt)));
+ return certificates;
+}
+
+constexpr char kRemoteFingerprintAlgorithm1[] = "sha-256";
+constexpr char kRemoteFingerprintValue1[] =
+ "8E:57:5F:8E:65:D2:83:7B:05:97:BB:72:DE:09:DE:03:BD:95:9B:A0:03:10:50:82:"
+ "5E:73:38:16:4C:E0:C5:84";
+
+RTCDtlsFingerprint CreateRemoteFingerprint1() {
+ RTCDtlsFingerprint dtls_fingerprint;
+ dtls_fingerprint.setAlgorithm(kRemoteFingerprintAlgorithm1);
+ dtls_fingerprint.setValue(kRemoteFingerprintValue1);
+ return dtls_fingerprint;
+}
+
+RTCQuicParameters CreateRemoteRTCQuicParameters1() {
+ HeapVector<RTCDtlsFingerprint> fingerprints;
+ fingerprints.push_back(CreateRemoteFingerprint1());
+ RTCQuicParameters quic_parameters;
+ quic_parameters.setFingerprints(fingerprints);
+ return quic_parameters;
+}
+
+} // namespace
+
+RTCQuicTransport* RTCQuicTransportTest::CreateQuicTransport(
+ V8TestingScope& scope,
+ RTCIceTransport* ice_transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ std::unique_ptr<MockP2PQuicTransport> mock_transport,
+ P2PQuicTransport::Delegate** delegate_out) {
+ return CreateQuicTransport(scope, ice_transport, certificates,
+ std::make_unique<MockP2PQuicTransportFactory>(
+ std::move(mock_transport), delegate_out));
+}
+
+RTCQuicTransport* RTCQuicTransportTest::CreateQuicTransport(
+ V8TestingScope& scope,
+ RTCIceTransport* ice_transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ std::unique_ptr<MockP2PQuicTransportFactory> mock_factory) {
+ return RTCQuicTransport::Create(scope.GetExecutionContext(), ice_transport,
+ certificates, ASSERT_NO_EXCEPTION,
+ std::move(mock_factory));
+}
+
+// Test that calling start() creates a P2PQuicTransport with the correct
+// P2PQuicTransportConfig. The config should have:
+// 1. The P2PQuicPacketTransport returned by the MockIceTransportAdapter.
+// 2. Server mode configured since the ICE role is 'controlling'.
+// 3. The certificates passed in the RTCQuicTransport constructor.
+TEST_F(RTCQuicTransportTest, P2PQuicTransportConstructedByStart) {
+ V8TestingScope scope;
+
+ auto quic_packet_transport = std::make_unique<MockP2PQuicPacketTransport>();
+ auto* quic_packet_transport_ptr = quic_packet_transport.get();
+ auto ice_transport_adapter_mock = std::make_unique<MockIceTransportAdapter>(
+ std::move(quic_packet_transport));
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(ice_transport_adapter_mock));
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate =
+ rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams::ECDSA(),
+ absl::nullopt);
+ auto mock_factory = std::make_unique<MockP2PQuicTransportFactory>(
+ std::make_unique<MockP2PQuicTransport>());
+ EXPECT_CALL(*mock_factory, OnCreateQuicTransport(_))
+ .WillOnce(Invoke([quic_packet_transport_ptr,
+ certificate](const P2PQuicTransportConfig& config) {
+ EXPECT_EQ(quic_packet_transport_ptr, config.packet_transport);
+ EXPECT_TRUE(config.is_server);
+ EXPECT_THAT(config.certificates, ElementsAre(certificate));
+ }));
+ HeapVector<Member<RTCCertificate>> certificates;
+ certificates.push_back(new RTCCertificate(certificate));
+ Persistent<RTCQuicTransport> quic_transport = CreateQuicTransport(
+ scope, ice_transport, certificates, std::move(mock_factory));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling start() creates a P2PQuicTransport with
+// |config.is_server| = false if the RTCIceTransport role is 'controlled'.
+TEST_F(RTCQuicTransportTest, P2PQuicTransportConstructedByStartClient) {
+ V8TestingScope scope;
+
+ auto ice_transport_adapter_mock = std::make_unique<MockIceTransportAdapter>(
+ std::make_unique<MockP2PQuicPacketTransport>());
+ Persistent<RTCIceTransport> ice_transport =
+ CreateIceTransport(scope, std::move(ice_transport_adapter_mock));
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlled",
+ ASSERT_NO_EXCEPTION);
+
+ auto mock_factory = std::make_unique<MockP2PQuicTransportFactory>(
+ std::make_unique<MockP2PQuicTransport>());
+ EXPECT_CALL(*mock_factory, OnCreateQuicTransport(_))
+ .WillOnce(Invoke([](const P2PQuicTransportConfig& config) {
+ EXPECT_FALSE(config.is_server);
+ }));
+ Persistent<RTCQuicTransport> quic_transport =
+ CreateQuicTransport(scope, ice_transport, GenerateLocalRTCCertificates(),
+ std::move(mock_factory));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling start() calls Start() on the P2PQuicTransport with the
+// correct remote fingerprints.
+TEST_F(RTCQuicTransportTest, StartPassesRemoteFingerprints) {
+ V8TestingScope scope;
+
+ Persistent<RTCIceTransport> ice_transport = CreateIceTransport(scope);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ auto mock_transport = std::make_unique<MockP2PQuicTransport>();
+ EXPECT_CALL(*mock_transport, MockStart(_))
+ .WillOnce(
+ Invoke([](const std::vector<std::unique_ptr<rtc::SSLFingerprint>>&
+ remote_fingerprints) {
+ ASSERT_EQ(1u, remote_fingerprints.size());
+ EXPECT_EQ(kRemoteFingerprintAlgorithm1,
+ remote_fingerprints[0]->algorithm);
+ EXPECT_EQ(kRemoteFingerprintValue1,
+ remote_fingerprints[0]->GetRfc4572Fingerprint());
+ }));
+ Persistent<RTCQuicTransport> quic_transport =
+ CreateQuicTransport(scope, ice_transport, GenerateLocalRTCCertificates(),
+ std::move(mock_transport));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+}
+
+// Test that calling stop() deletes the underlying P2PQuicTransport.
+TEST_F(RTCQuicTransportTest, StopCallsStopThenDeletesQuicTransportAdapter) {
+ V8TestingScope scope;
+
+ Persistent<RTCIceTransport> ice_transport = CreateIceTransport(scope);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ bool mock_deleted = false;
+ auto mock_transport = std::make_unique<MockP2PQuicTransport>();
+ EXPECT_CALL(*mock_transport, Stop()).Times(1);
+ EXPECT_CALL(*mock_transport, Die()).WillOnce(Assign(&mock_deleted, true));
+
+ Persistent<RTCQuicTransport> quic_transport =
+ CreateQuicTransport(scope, ice_transport, GenerateLocalRTCCertificates(),
+ std::move(mock_transport));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+
+ quic_transport->stop();
+ RunUntilIdle();
+
+ EXPECT_TRUE(mock_deleted);
+}
+
+// Test that calling stop() on the underlying RTCIceTransport deletes the
+// underlying P2PQuicTransport.
+TEST_F(RTCQuicTransportTest, RTCIceTransportStopDeletesP2PQuicTransport) {
+ V8TestingScope scope;
+
+ Persistent<RTCIceTransport> ice_transport = CreateIceTransport(scope);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ bool mock_deleted = false;
+ auto mock_transport = std::make_unique<MockP2PQuicTransport>();
+ EXPECT_CALL(*mock_transport, Die()).WillOnce(Assign(&mock_deleted, true));
+
+ Persistent<RTCQuicTransport> quic_transport =
+ CreateQuicTransport(scope, ice_transport, GenerateLocalRTCCertificates(),
+ std::move(mock_transport));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+
+ ice_transport->stop();
+ RunUntilIdle();
+
+ EXPECT_TRUE(mock_deleted);
+}
+
+// Test that the P2PQuicTransport is deleted when the underlying RTCIceTransport
+// is ContextDestroyed.
+TEST_F(RTCQuicTransportTest,
+ RTCIceTransportContextDestroyedDeletesP2PQuicTransport) {
+ V8TestingScope scope;
+
+ Persistent<RTCIceTransport> ice_transport = CreateIceTransport(scope);
+ ice_transport->start(CreateRemoteRTCIceParameters1(), "controlling",
+ ASSERT_NO_EXCEPTION);
+
+ bool mock_deleted = false;
+ auto mock_transport = std::make_unique<MockP2PQuicTransport>();
+ EXPECT_CALL(*mock_transport, Die()).WillOnce(Assign(&mock_deleted, true));
+
+ Persistent<RTCQuicTransport> quic_transport =
+ CreateQuicTransport(scope, ice_transport, GenerateLocalRTCCertificates(),
+ std::move(mock_transport));
+ quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
+
+ ice_transport->ContextDestroyed(scope.GetExecutionContext());
+ RunUntilIdle();
+
+ EXPECT_TRUE(mock_deleted);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.h
new file mode 100644
index 00000000000..05683f98c4c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.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 LQUICNSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_TEST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_TEST_H_
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_transport_factory.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
+
+namespace blink {
+
+class RTCQuicTransportTest : public RTCIceTransportTest {
+ public:
+ // Construct a new RTCQuicTransport with the given RTCIceTransport,
+ // certificates, and mock P2PQuicTransport.
+ // |delegate_out|, if non-null, will be populated once the P2PQuicTransport is
+ // constructed on the worker thread.
+ RTCQuicTransport* CreateQuicTransport(
+ V8TestingScope& scope,
+ RTCIceTransport* ice_transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ std::unique_ptr<MockP2PQuicTransport> mock_transport,
+ P2PQuicTransport::Delegate** delegate_out = nullptr);
+
+ // Construct a new RTCQuicTransport with the given RTCIceTransport,
+ // certificates, and mock P2PQuicTransportFactory.
+ RTCQuicTransport* CreateQuicTransport(
+ V8TestingScope& scope,
+ RTCIceTransport* ice_transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ std::unique_ptr<MockP2PQuicTransportFactory> mock_factory);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_TEST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
index 789a24c2bea..91e6757baf6 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
@@ -79,9 +79,9 @@ webrtc::RtpTransceiverInit ToRtpTransceiverInit(
webrtc_init.stream_ids.push_back(stream->id().Utf8().data());
}
DCHECK(init.hasSendEncodings());
- // TODO(orphis,hbos): Pass the encodings down to the lower layer using
- // ToRtpEncodingParameters() once implemented in third_party/webrtc.
- // https://crbug.com/803494
+ for (const auto& encoding : init.sendEncodings()) {
+ webrtc_init.send_encodings.push_back(ToRtpEncodingParameters(encoding));
+ }
return webrtc_init;
}
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl b/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
index 9d5e8edd646..d222ccbd270 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
@@ -2,18 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// https://w3c.github.io/permissions/#enumdef-permissionname
enum PermissionName {
"geolocation",
- "midi",
"notifications",
"push",
+ "midi",
"camera",
"microphone",
+ // "speaker",
+ // "device-info",
+ "background-fetch",
"background-sync",
+ // "bluetooth",
+ "persistent-storage",
"ambient-light-sensor",
"accelerometer",
"gyroscope",
"magnetometer",
+ // "clipboard",
+
+ // Non-standard:
"accessibility-events",
"clipboard-read",
"clipboard-write",
@@ -23,6 +32,7 @@ enum PermissionName {
// The PermissionDescriptor dictionary is a base to describe permissions. Some
// permissions will extend it. The methods reading it will re-parse it depending
// on the name.
+// https://w3c.github.io/permissions/#dictdef-permissiondescriptor
dictionary PermissionDescriptor {
required PermissionName name;
};
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
index 20d74e84b64..4b57a3013a2 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -68,6 +68,8 @@ PermissionDescriptorPtr ParsePermission(ScriptState* script_state,
return CreatePermissionDescriptor(PermissionName::AUDIO_CAPTURE);
if (name == "notifications")
return CreatePermissionDescriptor(PermissionName::NOTIFICATIONS);
+ if (name == "persistent-storage")
+ return CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE);
if (name == "push") {
PushPermissionDescriptor push_permission =
NativeValueTraits<PushPermissionDescriptor>::NativeValue(
@@ -137,6 +139,14 @@ PermissionDescriptorPtr ParsePermission(ScriptState* script_state,
}
if (name == "payment-handler")
return CreatePermissionDescriptor(PermissionName::PAYMENT_HANDLER);
+ if (name == "background-fetch") {
+ if (!OriginTrials::BackgroundFetchEnabled(
+ ExecutionContext::From(script_state))) {
+ exception_state.ThrowTypeError("Background Fetch is not enabled.");
+ return nullptr;
+ }
+ return CreatePermissionDescriptor(PermissionName::BACKGROUND_FETCH);
+ }
return nullptr;
}
@@ -181,13 +191,13 @@ ScriptPromise Permissions::request(ScriptState* script_state,
ScriptPromise promise = resolver->Promise();
PermissionDescriptorPtr descriptor_copy = descriptor->Clone();
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = DynamicTo<Document>(context);
LocalFrame* frame = doc ? doc->GetFrame() : nullptr;
GetService(ExecutionContext::From(script_state))
.RequestPermission(
std::move(descriptor),
- Frame::HasTransientUserActivation(frame,
- true /* checkIfMainThread */),
+ LocalFrame::HasTransientUserActivation(
+ frame, true /* check_if_main_thread */),
WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this),
WrapPersistent(resolver),
WTF::Passed(std::move(descriptor_copy))));
@@ -255,13 +265,13 @@ ScriptPromise Permissions::requestAll(
for (const auto& descriptor : internal_permissions)
internal_permissions_copy.push_back(descriptor->Clone());
- Document* doc = ToDocumentOrNull(context);
+ Document* doc = DynamicTo<Document>(context);
LocalFrame* frame = doc ? doc->GetFrame() : nullptr;
GetService(ExecutionContext::From(script_state))
.RequestPermissions(
std::move(internal_permissions),
- Frame::HasTransientUserActivation(frame,
- true /* checkIfMainThread */),
+ LocalFrame::HasTransientUserActivation(
+ frame, true /* check_if_main_thread */),
WTF::Bind(&Permissions::BatchTaskComplete, WrapPersistent(this),
WrapPersistent(resolver),
WTF::Passed(std::move(internal_permissions_copy)),
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
index 6c2d74cf411..2628c46dc9a 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
@@ -33,7 +33,7 @@ ScriptPromise DocumentPictureInPicture::exitPictureInPicture(
PictureInPictureControllerImpl& controller =
PictureInPictureControllerImpl::From(document);
Element* picture_in_picture_element =
- controller.PictureInPictureElement(ToTreeScope(document));
+ controller.PictureInPictureElement(document);
if (!picture_in_picture_element) {
return ScriptPromise::RejectWithDOMException(
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
index 4b869169e28..a07678ca9c5 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.h"
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
namespace blink {
@@ -28,8 +27,6 @@ const char kMetadataNotLoadedError[] =
"Metadata for the video element are not loaded yet.";
const char kVideoTrackNotAvailableError[] =
"The video element has no video track.";
-const char kMediaStreamsNotSupportedYet[] =
- "Media Streams are not supported yet.";
const char kFeaturePolicyBlocked[] =
"Access to the feature \"picture-in-picture\" is disallowed by feature "
"policy.";
@@ -64,11 +61,6 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
script_state,
DOMException::Create(DOMExceptionCode::kInvalidStateError,
kVideoTrackNotAvailableError));
- case Status::kMediaStreamsNotSupportedYet:
- return ScriptPromise::RejectWithDOMException(
- script_state,
- DOMException::Create(DOMExceptionCode::kNotSupportedError,
- kMediaStreamsNotSupportedYet));
case Status::kDisabledByFeaturePolicy:
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
@@ -91,7 +83,7 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
// `kFrameDetached`.
LocalFrame* frame = element.GetFrame();
DCHECK(frame);
- if (!Frame::ConsumeTransientUserActivation(frame)) {
+ if (!LocalFrame::ConsumeTransientUserActivation(frame)) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kNotAllowedError,
kUserGestureRequired));
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
index 163159c6508..c8ff90a439d 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
-#include "third_party/blink/public/platform/web_media_player.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h"
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -55,8 +54,9 @@ PictureInPictureControllerImpl::IsDocumentAllowed() const {
// If document is not allowed to use the policy-controlled feature named
// "picture-in-picture", return kDisabledByFeaturePolicy status.
if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled() &&
- !frame->IsFeatureEnabled(
- blink::mojom::FeaturePolicyFeature::kPictureInPicture)) {
+ !GetSupplementable()->IsFeatureEnabled(
+ blink::mojom::FeaturePolicyFeature::kPictureInPicture,
+ ReportOptions::kReportOnFailure)) {
return Status::kDisabledByFeaturePolicy;
}
@@ -79,10 +79,6 @@ PictureInPictureControllerImpl::IsElementAllowed(
if (element.FastHasAttribute(HTMLNames::disablepictureinpictureAttr))
return Status::kDisabledByAttribute;
- // TODO(crbug.com/806249): Remove this when MediaStreams are supported.
- if (element.GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream)
- return Status::kMediaStreamsNotSupportedYet;
-
return Status::kEnabled;
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
index a677e26afa3..8c3c92da83a 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
@@ -35,7 +35,7 @@ PresentationAvailability::PresentationAvailability(
const WTF::Vector<KURL>& urls,
bool value)
: PausableObject(execution_context),
- PageVisibilityObserver(ToDocument(execution_context)->GetPage()),
+ PageVisibilityObserver(To<Document>(execution_context)->GetPage()),
urls_(urls),
value_(value),
state_(State::kActive) {
@@ -107,7 +107,7 @@ void PresentationAvailability::UpdateListening() {
return;
if (state_ == State::kActive &&
- (ToDocument(GetExecutionContext())->GetPageVisibilityState() ==
+ (To<Document>(GetExecutionContext())->GetPageVisibilityState() ==
mojom::PageVisibilityState::kVisible))
controller->GetAvailabilityState()->AddObserver(this);
else
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
index ee609bef2f3..ba08fa134d9 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc
@@ -5,9 +5,9 @@
#include "third_party/blink/renderer/modules/presentation/presentation_availability_state.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/modules/presentation/presentation_availability_observer.h"
#include "third_party/blink/renderer/modules/presentation/presentation_controller.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc
index f3fc8efe0cc..a828aa58912 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc
@@ -97,7 +97,7 @@ class PresentationAvailabilityStateTest : public testing::Test {
state_.RequestAvailability(
urls,
std::unique_ptr<MockPresentationAvailabilityCallbacks>(mock_callback));
- for (size_t i = 0; i < urls.size(); i++)
+ for (wtf_size_t i = 0; i < urls.size(); i++)
ChangeURLState(urls[i], states[i]);
}
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
index 42711dda72b..68acf374d54 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -166,29 +166,23 @@ PresentationConnection::~PresentationConnection() {
}
void PresentationConnection::OnMessage(
- mojom::blink::PresentationConnectionMessagePtr message,
- OnMessageCallback callback) {
- DCHECK(!callback.is_null());
+ mojom::blink::PresentationConnectionMessagePtr message) {
if (message->is_data()) {
const auto& data = message->get_data();
DidReceiveBinaryMessage(&data.front(), data.size());
} else {
DidReceiveTextMessage(message->get_message());
}
-
- std::move(callback).Run(true);
}
void PresentationConnection::DidChangeState(
mojom::blink::PresentationConnectionState state) {
+ // Closed state is handled in |DidClose()|.
+ DCHECK_NE(mojom::blink::PresentationConnectionState::CLOSED, state);
+
if (state_ == state)
return;
- if (state == mojom::blink::PresentationConnectionState::CLOSED) {
- DidClose();
- return;
- }
-
state_ = state;
switch (state_) {
@@ -197,7 +191,6 @@ void PresentationConnection::DidChangeState(
case mojom::blink::PresentationConnectionState::CONNECTED:
DispatchStateChangeEvent(Event::Create(EventTypeNames::connect));
return;
- // Closed state is handled in |DidClose()|.
case mojom::blink::PresentationConnectionState::CLOSED:
return;
case mojom::blink::PresentationConnectionState::TERMINATED:
@@ -207,15 +200,9 @@ void PresentationConnection::DidChangeState(
NOTREACHED();
}
-void PresentationConnection::RequestClose() {
- DidChangeState(mojom::blink::PresentationConnectionState::CLOSED);
-
- // TODO(crbug.com/749327): Instead of calling DidChangeState, consider
- // supplying a callback to RequestClose() and invoking it here.
- if (target_connection_) {
- target_connection_->DidChangeState(
- mojom::blink::PresentationConnectionState::CLOSED);
- }
+void PresentationConnection::DidClose(
+ mojom::blink::PresentationConnectionCloseReason reason) {
+ DidClose(reason, /* message */ String());
}
// static
@@ -225,9 +212,8 @@ ControllerPresentationConnection* ControllerPresentationConnection::Take(
PresentationRequest* request) {
DCHECK(resolver);
DCHECK(request);
- DCHECK(resolver->GetExecutionContext()->IsDocument());
- Document* document = ToDocument(resolver->GetExecutionContext());
+ Document* document = To<Document>(resolver->GetExecutionContext());
if (!document->GetFrame())
return nullptr;
@@ -271,7 +257,7 @@ ControllerPresentationConnection::ControllerPresentationConnection(
const KURL& url)
: PresentationConnection(frame, id, url), controller_(controller) {}
-ControllerPresentationConnection::~ControllerPresentationConnection() = default;
+ControllerPresentationConnection::~ControllerPresentationConnection() {}
void ControllerPresentationConnection::Trace(blink::Visitor* visitor) {
visitor->Trace(controller_);
@@ -295,13 +281,13 @@ void ControllerPresentationConnection::Init(
connection_binding_.Bind(std::move(connection_request));
}
-void ControllerPresentationConnection::DoClose() {
+void ControllerPresentationConnection::CloseInternal() {
auto& service = controller_->GetPresentationService();
if (service)
service->CloseConnection(url_, id_);
}
-void ControllerPresentationConnection::DoTerminate() {
+void ControllerPresentationConnection::TerminateInternal() {
auto& service = controller_->GetPresentationService();
if (service)
service->Terminate(url_, id_);
@@ -350,15 +336,19 @@ void ReceiverPresentationConnection::Init(
void ReceiverPresentationConnection::DidChangeState(
mojom::blink::PresentationConnectionState state) {
PresentationConnection::DidChangeState(state);
- if (state == mojom::blink::PresentationConnectionState::CLOSED)
- receiver_->RemoveConnection(this);
}
-void ReceiverPresentationConnection::DoClose() {
+void ReceiverPresentationConnection::DidClose(
+ mojom::blink::PresentationConnectionCloseReason reason) {
+ PresentationConnection::DidClose(reason);
+ receiver_->RemoveConnection(this);
+}
+
+void ReceiverPresentationConnection::CloseInternal() {
// No-op
}
-void ReceiverPresentationConnection::DoTerminate() {
+void ReceiverPresentationConnection::TerminateInternal() {
// This will close the receiver window. Change the state to TERMINATED now
// since ReceiverPresentationConnection won't get a state change notification.
if (state_ == mojom::blink::PresentationConnectionState::TERMINATED)
@@ -408,6 +398,7 @@ void PresentationConnection::AddedEventListener(
}
void PresentationConnection::ContextDestroyed(ExecutionContext*) {
+ DoClose(mojom::blink::PresentationConnectionCloseReason::WENT_AWAY);
target_connection_.reset();
connection_binding_.Close();
}
@@ -463,6 +454,21 @@ void PresentationConnection::send(Blob* data, ExceptionState& exception_state) {
HandleMessageQueue();
}
+void PresentationConnection::DoClose(
+ mojom::blink::PresentationConnectionCloseReason reason) {
+ if (state_ != mojom::blink::PresentationConnectionState::CONNECTING &&
+ state_ != mojom::blink::PresentationConnectionState::CONNECTED) {
+ return;
+ }
+
+ if (target_connection_)
+ target_connection_->DidClose(reason);
+
+ DidClose(reason);
+ CloseInternal();
+ TearDown();
+}
+
bool PresentationConnection::CanSendMessage(ExceptionState& exception_state) {
if (state_ != mojom::blink::PresentationConnectionState::CONNECTED) {
ThrowPresentationDisconnectedError(exception_state);
@@ -520,10 +526,8 @@ void PresentationConnection::setBinaryType(const String& binary_type) {
void PresentationConnection::SendMessageToTargetConnection(
mojom::blink::PresentationConnectionMessagePtr message) {
- if (target_connection_) {
- target_connection_->OnMessage(std::move(message),
- base::OnceCallback<void(bool)>());
- }
+ if (target_connection_)
+ target_connection_->OnMessage(std::move(message));
}
void PresentationConnection::DidReceiveTextMessage(const WebString& message) {
@@ -534,7 +538,7 @@ void PresentationConnection::DidReceiveTextMessage(const WebString& message) {
}
void PresentationConnection::DidReceiveBinaryMessage(const uint8_t* data,
- size_t length) {
+ uint32_t length) {
if (state_ != mojom::blink::PresentationConnectionState::CONNECTED)
return;
@@ -561,23 +565,14 @@ mojom::blink::PresentationConnectionState PresentationConnection::GetState()
}
void PresentationConnection::close() {
- if (state_ != mojom::blink::PresentationConnectionState::CONNECTING &&
- state_ != mojom::blink::PresentationConnectionState::CONNECTED) {
- return;
- }
-
- if (target_connection_)
- target_connection_->RequestClose();
-
- DoClose();
- TearDown();
+ DoClose(mojom::blink::PresentationConnectionCloseReason::CLOSED);
}
void PresentationConnection::terminate() {
if (state_ != mojom::blink::PresentationConnectionState::CONNECTED)
return;
- DoTerminate();
+ TerminateInternal();
TearDown();
}
@@ -598,10 +593,6 @@ void PresentationConnection::DidClose(
EventTypeNames::close, ConnectionCloseReasonToString(reason), message));
}
-void PresentationConnection::DidClose() {
- DidClose(mojom::blink::PresentationConnectionCloseReason::CLOSED, "");
-}
-
void PresentationConnection::DidFinishLoadingBlob(DOMArrayBuffer* buffer) {
DCHECK(!messages_.IsEmpty());
DCHECK_EQ(messages_.front()->type, kMessageTypeBlob);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
index c6adf86ff57..3168d5bad32 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -53,7 +53,12 @@ class PresentationConnection : public EventTargetWithInlineData,
void send(DOMArrayBuffer*, ExceptionState&);
void send(NotShared<DOMArrayBufferView>, ExceptionState&);
void send(Blob*, ExceptionState&);
+
+ // Closes the connection to the ongoing presentation.
void close();
+
+ // Terminates the ongoing presentation that this PresentationConnection is
+ // connected to.
void terminate();
String binaryType() const;
@@ -73,10 +78,9 @@ class PresentationConnection : public EventTargetWithInlineData,
const String& message);
// mojom::blink::PresentationConnection implementation.
- void OnMessage(mojom::blink::PresentationConnectionMessagePtr,
- OnMessageCallback) override;
+ void OnMessage(mojom::blink::PresentationConnectionMessagePtr) override;
void DidChangeState(mojom::blink::PresentationConnectionState) override;
- void RequestClose() override;
+ void DidClose(mojom::blink::PresentationConnectionCloseReason) override;
mojom::blink::PresentationConnectionState GetState() const;
@@ -118,9 +122,9 @@ class PresentationConnection : public EventTargetWithInlineData,
class Message;
// Implemented by controller/receiver subclasses to perform additional
- // operations.
- virtual void DoClose() = 0;
- virtual void DoTerminate() = 0;
+ // operations when close() / terminate() is called.
+ virtual void CloseInternal() = 0;
+ virtual void TerminateInternal() = 0;
bool CanSendMessage(ExceptionState&);
void HandleMessageQueue();
@@ -132,11 +136,11 @@ class PresentationConnection : public EventTargetWithInlineData,
void SendMessageToTargetConnection(
mojom::blink::PresentationConnectionMessagePtr);
void DidReceiveTextMessage(const WebString&);
- void DidReceiveBinaryMessage(const uint8_t*, size_t length);
+ void DidReceiveBinaryMessage(const uint8_t*, uint32_t length);
- // Notifies the presentation about its state change to 'closed', with
- // "closed" being the reason and empty string as the message.
- void DidClose();
+ // Closes the PresentationConnection with the given reason and notifies the
+ // target connection.
+ void DoClose(mojom::blink::PresentationConnectionCloseReason);
// Internal helper function to dispatch state change events asynchronously.
void DispatchStateChangeEvent(Event*);
@@ -179,8 +183,8 @@ class ControllerPresentationConnection final : public PresentationConnection {
private:
// PresentationConnection implementation.
- void DoClose() override;
- void DoTerminate() override;
+ void CloseInternal() override;
+ void TerminateInternal() override;
Member<PresentationController> controller_;
};
@@ -211,16 +215,17 @@ class ReceiverPresentationConnection final : public PresentationConnection {
// PresentationConnection override
void DidChangeState(mojom::blink::PresentationConnectionState) override;
+ void DidClose(mojom::blink::PresentationConnectionCloseReason) override;
private:
// PresentationConnection implementation.
- void DoClose() override;
+ void CloseInternal() override;
// Changes the presentation state to TERMINATED and notifies the sender
// connection. This method does not dispatch a state change event to the page.
// This method is only suitable for use when the presentation receiver frame
// containing the connection object is going away.
- void DoTerminate() override;
+ void TerminateInternal() override;
Member<PresentationReceiver> receiver_;
};
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
index bbff94f019f..79c0c3d1d8d 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_CONNECTION_CALLBACKS_H_
#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
index b3e4f0017bc..b706fc951ad 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc
@@ -43,7 +43,7 @@ void PresentationConnectionList::AddConnection(
bool PresentationConnectionList::RemoveConnection(
ReceiverPresentationConnection* connection) {
- for (size_t i = 0; i < connections_.size(); i++) {
+ for (wtf_size_t i = 0; i < connections_.size(); i++) {
if (connections_[i] == connection) {
connections_.EraseAt(i);
return true;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
index a9a3e752cfa..0bb8d0c060e 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -44,8 +44,7 @@ PresentationController* PresentationController::FromContext(
if (!execution_context)
return nullptr;
- DCHECK(execution_context->IsDocument());
- Document* document = ToDocument(execution_context);
+ Document* document = To<Document>(execution_context);
if (!document->GetFrame())
return nullptr;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
index 4942ca775bd..8d11b2b41cc 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
@@ -33,7 +33,7 @@ namespace {
Settings* GetSettings(ExecutionContext* execution_context) {
DCHECK(execution_context);
- Document* document = ToDocument(execution_context);
+ Document* document = To<Document>(execution_context);
return document->GetSettings();
}
@@ -59,7 +59,7 @@ PresentationRequest* PresentationRequest::Create(
ExecutionContext* execution_context,
const Vector<String>& urls,
ExceptionState& exception_state) {
- if (ToDocument(execution_context)
+ if (To<Document>(execution_context)
->IsSandboxed(kSandboxPresentationController)) {
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-presentation' flag.");
@@ -67,13 +67,13 @@ PresentationRequest* PresentationRequest::Create(
}
Vector<KURL> parsed_urls;
- for (size_t i = 0; i < urls.size(); ++i) {
- const KURL& parsed_url = KURL(execution_context->Url(), urls[i]);
+ for (const auto& url : urls) {
+ const KURL& parsed_url = KURL(execution_context->Url(), url);
if (!parsed_url.IsValid()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
- "'" + urls[i] + "' can't be resolved to a valid URL.");
+ "'" + url + "' can't be resolved to a valid URL.");
return nullptr;
}
@@ -81,7 +81,7 @@ PresentationRequest* PresentationRequest::Create(
MixedContentChecker::IsMixedContent(
execution_context->GetSecurityOrigin(), parsed_url)) {
exception_state.ThrowSecurityError(
- "Presentation of an insecure document [" + urls[i] +
+ "Presentation of an insecure document [" + url +
"] is prohibited from a secure context.");
return nullptr;
}
@@ -148,14 +148,14 @@ void PresentationRequest::RecordStartOriginTypeAccess(
ScriptPromise PresentationRequest::start(ScriptState* script_state) {
ExecutionContext* execution_context = GetExecutionContext();
Settings* context_settings = GetSettings(execution_context);
- Document* doc = ToDocumentOrNull(execution_context);
+ Document* doc = To<Document>(execution_context);
bool is_user_gesture_required =
!context_settings ||
context_settings->GetPresentationRequiresUserGesture();
if (is_user_gesture_required &&
- !Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr))
+ !LocalFrame::HasTransientUserActivation(doc->GetFrame()))
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
index 6ec4b2964ed..a4760fba894 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc
@@ -70,8 +70,8 @@ ScriptPromise PushManager::subscribe(ScriptState* script_state,
// The document context is the only reasonable context from which to ask the
// user for permission to use the Push API. The embedder should persist the
// permission so that later calls in different contexts can succeed.
- if (ExecutionContext::From(script_state)->IsDocument()) {
- Document* document = ToDocument(ExecutionContext::From(script_state));
+ if (auto* document =
+ DynamicTo<Document>(ExecutionContext::From(script_state))) {
LocalFrame* frame = document->GetFrame();
if (!document->domWindow() || !frame)
return ScriptPromise::RejectWithDOMException(
@@ -80,13 +80,14 @@ ScriptPromise PushManager::subscribe(ScriptState* script_state,
"Document is detached from window."));
PushController::ClientFrom(frame).Subscribe(
registration_->WebRegistration(), web_options,
- Frame::HasTransientUserActivation(frame, true /* checkIfMainThread */),
+ LocalFrame::HasTransientUserActivation(frame,
+ true /* check_if_main_thread */),
std::make_unique<PushSubscriptionCallbacks>(resolver, registration_));
} else {
PushProvider()->Subscribe(
registration_->WebRegistration(), web_options,
- Frame::HasTransientUserActivation(nullptr,
- true /* checkIfMainThread */),
+ LocalFrame::HasTransientUserActivation(nullptr,
+ true /* check_if_main_thread */),
std::make_unique<PushSubscriptionCallbacks>(resolver, registration_));
}
@@ -107,8 +108,8 @@ ScriptPromise PushManager::permissionState(
ScriptState* script_state,
const PushSubscriptionOptionsInit& options,
ExceptionState& exception_state) {
- if (ExecutionContext::From(script_state)->IsDocument()) {
- Document* document = ToDocument(ExecutionContext::From(script_state));
+ if (auto* document =
+ DynamicTo<Document>(ExecutionContext::From(script_state))) {
if (!document->domWindow() || !document->GetFrame())
return ScriptPromise::RejectWithDOMException(
script_state,
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
index e5f0b9a6c57..6282e7acfe5 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
@@ -43,7 +43,7 @@ PushMessageData* PushMessageData::Create(
if (message_data.IsUSVString()) {
CString encoded_string = UTF8Encoding().Encode(
- message_data.GetAsUSVString(), WTF::kEntitiesForUnencodables);
+ message_data.GetAsUSVString(), WTF::kNoUnencodables);
return new PushMessageData(encoded_string.data(), encoded_string.length());
}
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h
index 3f1465aeefc..655af998dfd 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_SUBSCRIPTION_CALLBACKS_H_
#include "third_party/blink/public/platform/modules/push_messaging/web_push_provider.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
index 2b9c1cb4e92..f0f64389878 100644
--- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
@@ -164,10 +164,7 @@ void DeprecatedStorageQuota::requestQuota(
unsigned long long new_quota_in_bytes,
V8StorageQuotaCallback* success_callback,
V8StorageErrorCallback* error_callback) {
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- DCHECK(execution_context);
- DCHECK(execution_context->IsDocument())
- << "Quota requests are not supported in workers";
+ ExecutionContext& execution_context = *ExecutionContext::From(script_state);
StorageType storage_type = GetStorageType(type_);
if (storage_type != StorageType::kTemporary &&
@@ -183,15 +180,15 @@ void DeprecatedStorageQuota::requestQuota(
WrapPersistent(ToV8PersistentCallbackFunction(success_callback)),
WrapPersistent(ToV8PersistentCallbackFunction(error_callback)));
- Document* document = ToDocument(execution_context);
- const SecurityOrigin* security_origin = document->GetSecurityOrigin();
+ Document& document = To<Document>(execution_context);
+ const SecurityOrigin* security_origin = document.GetSecurityOrigin();
if (security_origin->IsOpaque()) {
// Unique origins cannot store persistent state.
std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
return;
}
- GetQuotaHost(execution_context)
+ GetQuotaHost(&execution_context)
.RequestStorageQuota(
WrapRefCounted(security_origin), storage_type, new_quota_in_bytes,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
index 297e370f686..609ec79ad5c 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -64,12 +64,11 @@ ScriptPromise StorageManager::persist(ScriptState* script_state) {
return promise;
}
- DCHECK(execution_context->IsDocument());
- Document* doc = ToDocumentOrNull(execution_context);
+ Document* doc = To<Document>(execution_context);
GetPermissionService(ExecutionContext::From(script_state))
.RequestPermission(
CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE),
- Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
+ LocalFrame::HasTransientUserActivation(doc->GetFrame()),
WTF::Bind(&StorageManager::PermissionRequestComplete,
WrapPersistent(this), WrapPersistent(resolver)));
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
index 12b81f08264..14cfc15eaac 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
@@ -10,7 +10,7 @@
#include "base/callback.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/compiler.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
index 4f50a227565..d20885bc586 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -184,7 +184,7 @@ ScriptPromise RemotePlayback::prompt(ScriptState* script_state) {
return promise;
}
- if (!Frame::HasTransientUserActivation(media_element_->GetFrame())) {
+ if (!LocalFrame::HasTransientUserActivation(media_element_->GetFrame())) {
resolver->Reject(DOMException::Create(
DOMExceptionCode::kInvalidAccessError,
"RemotePlayback::prompt() requires user gesture."));
@@ -227,8 +227,7 @@ bool RemotePlayback::HasPendingActivity() const {
}
void RemotePlayback::ContextDestroyed(ExecutionContext*) {
- target_presentation_connection_.reset();
- presentation_connection_binding_.Close();
+ CleanupConnections();
}
void RemotePlayback::PromptInternal() {
@@ -369,7 +368,9 @@ void RemotePlayback::StateChanged(WebRemotePlaybackState state) {
->MediaRemotingStopped(
WebLocalizedString::kMediaRemotingStopNoText);
}
+ CleanupConnections();
presentation_id_ = "";
+ presentation_url_ = KURL();
media_element_->FlingingStopped();
}
break;
@@ -465,6 +466,11 @@ void RemotePlayback::RemotePlaybackDisabled() {
}
}
+void RemotePlayback::CleanupConnections() {
+ target_presentation_connection_.reset();
+ presentation_connection_binding_.Close();
+}
+
void RemotePlayback::AvailabilityChanged(
mojom::blink::ScreenAvailability availability) {
DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled());
@@ -511,7 +517,6 @@ void RemotePlayback::OnConnectionSuccess(
StateChanged(WebRemotePlaybackState::kConnecting);
- // TODO(imcheng): Reset binding when remote playback stops.
DCHECK(!presentation_connection_binding_.is_bound());
auto* presentation_controller =
PresentationController::FromContext(GetExecutionContext());
@@ -548,10 +553,8 @@ void RemotePlayback::HandlePresentationResponse(
}
void RemotePlayback::OnMessage(
- mojom::blink::PresentationConnectionMessagePtr message,
- OnMessageCallback callback) {
+ mojom::blink::PresentationConnectionMessagePtr message) {
// Messages are ignored.
- std::move(callback).Run(true);
}
void RemotePlayback::DidChangeState(
@@ -566,7 +569,8 @@ void RemotePlayback::DidChangeState(
StateChanged(remote_playback_state);
}
-void RemotePlayback::RequestClose() {
+void RemotePlayback::DidClose(
+ mojom::blink::PresentationConnectionCloseReason reason) {
StateChanged(WebRemotePlaybackState::kDisconnected);
}
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
index fdf5b795580..9e5a48d9ada 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -106,10 +106,9 @@ class MODULES_EXPORT RemotePlayback final
void OnConnectionError(const mojom::blink::PresentationError&);
// mojom::blink::PresentationConnection implementation.
- void OnMessage(mojom::blink::PresentationConnectionMessagePtr,
- OnMessageCallback) override;
+ void OnMessage(mojom::blink::PresentationConnectionMessagePtr) override;
void DidChangeState(mojom::blink::PresentationConnectionState) override;
- void RequestClose() override;
+ void DidClose(mojom::blink::PresentationConnectionCloseReason) override;
// WebRemotePlaybackClient implementation.
void StateChanged(WebRemotePlaybackState) override;
@@ -151,6 +150,9 @@ class MODULES_EXPORT RemotePlayback final
// May be called more than once in a row.
void StopListeningForAvailability();
+ // Clears bindings after remote playback stops.
+ void CleanupConnections();
+
WebRemotePlaybackState state_;
WebRemotePlaybackAvailability availability_;
HeapHashMap<int, TraceWrapperMember<AvailabilityCallbackWrapper>>
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
index fa7b972603c..f283e8f2561 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
@@ -97,8 +97,9 @@ TEST_F(RemotePlaybackTest, PromptCancelledRejectsWithNotAllowedError) {
EXPECT_CALL(*resolve, Call(testing::_)).Times(0);
EXPECT_CALL(*reject, Call(testing::_)).Times(1);
- std::unique_ptr<UserGestureIndicator> indicator = Frame::NotifyUserActivation(
- &page_holder->GetFrame(), UserGestureToken::kNewGesture);
+ std::unique_ptr<UserGestureIndicator> indicator =
+ LocalFrame::NotifyUserActivation(&page_holder->GetFrame(),
+ UserGestureToken::kNewGesture);
remote_playback->prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
CancelPrompt(remote_playback);
@@ -130,8 +131,9 @@ TEST_F(RemotePlaybackTest, PromptConnectedRejectsWhenCancelled) {
SetState(remote_playback, WebRemotePlaybackState::kConnected);
- std::unique_ptr<UserGestureIndicator> indicator = Frame::NotifyUserActivation(
- &page_holder->GetFrame(), UserGestureToken::kNewGesture);
+ std::unique_ptr<UserGestureIndicator> indicator =
+ LocalFrame::NotifyUserActivation(&page_holder->GetFrame(),
+ UserGestureToken::kNewGesture);
remote_playback->prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
CancelPrompt(remote_playback);
@@ -163,8 +165,9 @@ TEST_F(RemotePlaybackTest, PromptConnectedResolvesWhenDisconnected) {
SetState(remote_playback, WebRemotePlaybackState::kConnected);
- std::unique_ptr<UserGestureIndicator> indicator = Frame::NotifyUserActivation(
- &page_holder->GetFrame(), UserGestureToken::kNewGesture);
+ std::unique_ptr<UserGestureIndicator> indicator =
+ LocalFrame::NotifyUserActivation(&page_holder->GetFrame(),
+ UserGestureToken::kNewGesture);
remote_playback->prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
@@ -239,8 +242,9 @@ TEST_F(RemotePlaybackTest,
EXPECT_CALL(*resolve, Call(testing::_)).Times(0);
EXPECT_CALL(*reject, Call(testing::_)).Times(1);
- std::unique_ptr<UserGestureIndicator> indicator = Frame::NotifyUserActivation(
- &page_holder->GetFrame(), UserGestureToken::kNewGesture);
+ std::unique_ptr<UserGestureIndicator> indicator =
+ LocalFrame::NotifyUserActivation(&page_holder->GetFrame(),
+ UserGestureToken::kNewGesture);
remote_playback->prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
HTMLMediaElementRemotePlayback::SetBooleanAttribute(
@@ -314,8 +318,9 @@ TEST_F(RemotePlaybackTest, PromptThrowsWhenBackendDisabled) {
EXPECT_CALL(*resolve, Call(testing::_)).Times(0);
EXPECT_CALL(*reject, Call(testing::_)).Times(1);
- std::unique_ptr<UserGestureIndicator> indicator = Frame::NotifyUserActivation(
- &page_holder->GetFrame(), UserGestureToken::kNewGesture);
+ std::unique_ptr<UserGestureIndicator> indicator =
+ LocalFrame::NotifyUserActivation(&page_holder->GetFrame(),
+ UserGestureToken::kNewGesture);
remote_playback->prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h b/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h
index 88b83dc8260..b700ad9b18c 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h
@@ -8,7 +8,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
#include "third_party/blink/renderer/modules/screen_orientation/web_lock_orientation_callback.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc
index 9d514753652..67512ed90df 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.cc
@@ -11,10 +11,10 @@
namespace blink {
ScreenOrientationDispatcher& ScreenOrientationDispatcher::Instance() {
- DEFINE_STATIC_LOCAL(ScreenOrientationDispatcher,
+ DEFINE_STATIC_LOCAL(Persistent<ScreenOrientationDispatcher>,
screen_orientation_dispatcher,
(new ScreenOrientationDispatcher));
- return screen_orientation_dispatcher;
+ return *screen_orientation_dispatcher;
}
ScreenOrientationDispatcher::ScreenOrientationDispatcher() = default;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/OWNERS b/chromium/third_party/blink/renderer/modules/sensor/OWNERS
index 655a26ab830..5419ed8e331 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/sensor/OWNERS
@@ -1,4 +1,3 @@
-alexander.shalamov@intel.com
reillyg@chromium.org
rijubrata.bhaumik@intel.com
timvolodine@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
index 484baee05b1..36fc02340d9 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -6,6 +6,7 @@
#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
#include "services/device/public/mojom/sensor.mojom-blink.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -14,7 +15,6 @@
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/modules/sensor/sensor_error_event.h"
#include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
namespace blink {
@@ -22,11 +22,11 @@ namespace blink {
namespace {
const double kWaitingIntervalThreshold = 0.01;
-bool AreFeaturesEnabled(LocalFrame* frame,
+bool AreFeaturesEnabled(Document* document,
const Vector<mojom::FeaturePolicyFeature>& features) {
return std::all_of(features.begin(), features.end(),
- [frame](mojom::FeaturePolicyFeature feature) {
- return frame->IsFeatureEnabled(feature);
+ [document](mojom::FeaturePolicyFeature feature) {
+ return document->IsFeatureEnabled(feature);
});
}
@@ -45,9 +45,9 @@ Sensor::Sensor(ExecutionContext* execution_context,
// [SecureContext] in idl.
DCHECK(execution_context->IsSecureContext());
DCHECK(!features.IsEmpty());
- LocalFrame* frame = ToDocument(execution_context)->GetFrame();
+ Document* document = To<Document>(execution_context);
- if (!frame || !AreFeaturesEnabled(frame, features)) {
+ if (!AreFeaturesEnabled(document, features)) {
exception_state.ThrowSecurityError(
"Access to sensor features is disallowed by feature policy");
return;
@@ -173,11 +173,11 @@ void Sensor::InitSensorProxyIfNeeded() {
if (sensor_proxy_)
return;
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
if (!document || !document->GetFrame())
return;
- auto* provider = SensorProviderProxy::From(document->GetFrame());
+ auto* provider = SensorProviderProxy::From(document);
sensor_proxy_ = provider->GetSensorProxy(type_);
if (!sensor_proxy_)
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
index d1acd73b023..296d24383da 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc
@@ -13,8 +13,8 @@
namespace blink {
-SensorInspectorAgent::SensorInspectorAgent(LocalFrame* frame)
- : provider_(SensorProviderProxy::From(frame)) {}
+SensorInspectorAgent::SensorInspectorAgent(Document* document)
+ : provider_(SensorProviderProxy::From(document)) {}
void SensorInspectorAgent::Trace(blink::Visitor* visitor) {
visitor->Trace(provider_);
@@ -59,11 +59,24 @@ const char kInspectorConsoleMessage[] =
} // namespace
+void SensorInspectorAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
+ Document* current_document = provider_->GetSupplementable();
+ Document* new_document = frame->GetDocument();
+ if (current_document != new_document) {
+ // We need to manually reset |provider_| to drop the strong reference it
+ // has to an old document that would otherwise be prevented from being
+ // deleted.
+ bool inspector_mode = provider_->inspector_mode();
+ provider_ = SensorProviderProxy::From(new_document);
+ provider_->set_inspector_mode(inspector_mode);
+ }
+}
+
void SensorInspectorAgent::SetOrientationSensorOverride(double alpha,
double beta,
double gamma) {
if (!provider_->inspector_mode()) {
- Document* document = provider_->GetSupplementable()->GetDocument();
+ Document* document = provider_->GetSupplementable();
if (document) {
ConsoleMessage* console_message = ConsoleMessage::Create(
kJSMessageSource, kInfoMessageLevel, kInspectorConsoleMessage);
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
index 42e3beada0f..932017e201c 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h
@@ -9,14 +9,17 @@
namespace blink {
+class Document;
class LocalFrame;
class SensorProviderProxy;
class SensorInspectorAgent : public GarbageCollected<SensorInspectorAgent> {
public:
- explicit SensorInspectorAgent(LocalFrame* frame);
+ explicit SensorInspectorAgent(Document* document);
virtual void Trace(blink::Visitor*);
+ void DidCommitLoadForLocalFrame(LocalFrame* frame);
+
void SetOrientationSensorOverride(double alpha, double beta, double gamma);
void Disable();
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
index 33df93deadf..d0cb3372ca1 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc
@@ -13,14 +13,14 @@
namespace blink {
// SensorProviderProxy
-SensorProviderProxy::SensorProviderProxy(LocalFrame& frame)
- : Supplement<LocalFrame>(frame), inspector_mode_(false) {}
+SensorProviderProxy::SensorProviderProxy(Document& document)
+ : Supplement<Document>(document), inspector_mode_(false) {}
void SensorProviderProxy::InitializeIfNeeded() {
if (IsInitialized())
return;
- GetSupplementable()->GetInterfaceProvider().GetInterface(
+ GetSupplementable()->GetInterfaceProvider()->GetInterface(
mojo::MakeRequest(&sensor_provider_));
sensor_provider_.set_connection_error_handler(
WTF::Bind(&SensorProviderProxy::OnSensorProviderConnectionError,
@@ -31,13 +31,13 @@ void SensorProviderProxy::InitializeIfNeeded() {
const char SensorProviderProxy::kSupplementName[] = "SensorProvider";
// static
-SensorProviderProxy* SensorProviderProxy::From(LocalFrame* frame) {
- DCHECK(frame);
+SensorProviderProxy* SensorProviderProxy::From(Document* document) {
+ DCHECK(document);
SensorProviderProxy* provider_proxy =
- Supplement<LocalFrame>::From<SensorProviderProxy>(*frame);
+ Supplement<Document>::From<SensorProviderProxy>(*document);
if (!provider_proxy) {
- provider_proxy = new SensorProviderProxy(*frame);
- Supplement<LocalFrame>::ProvideTo(*frame, provider_proxy);
+ provider_proxy = new SensorProviderProxy(*document);
+ Supplement<Document>::ProvideTo(*document, provider_proxy);
}
provider_proxy->InitializeIfNeeded();
return provider_proxy;
@@ -47,7 +47,7 @@ SensorProviderProxy::~SensorProviderProxy() = default;
void SensorProviderProxy::Trace(blink::Visitor* visitor) {
visitor->Trace(sensor_proxies_);
- Supplement<LocalFrame>::Trace(visitor);
+ Supplement<Document>::Trace(visitor);
}
SensorProxy* SensorProviderProxy::CreateSensorProxy(
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
index bad04f7d31f..324ca953dbd 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
@@ -7,7 +7,7 @@
#include "services/device/public/mojom/sensor.mojom-blink.h"
#include "services/device/public/mojom/sensor_provider.mojom-blink.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -19,14 +19,14 @@ class SensorProxy;
// 'SensorProxy' instances.
class SensorProviderProxy final
: public GarbageCollectedFinalized<SensorProviderProxy>,
- public Supplement<LocalFrame> {
+ public Supplement<Document> {
USING_GARBAGE_COLLECTED_MIXIN(SensorProviderProxy);
WTF_MAKE_NONCOPYABLE(SensorProviderProxy);
public:
static const char kSupplementName[];
- static SensorProviderProxy* From(LocalFrame*);
+ static SensorProviderProxy* From(Document*);
~SensorProviderProxy();
@@ -50,7 +50,7 @@ class SensorProviderProxy final
const SensorsSet& sensor_proxies() const { return sensor_proxies_; }
// For SensorProviderProxy personal use.
- explicit SensorProviderProxy(LocalFrame&);
+ explicit SensorProviderProxy(Document&);
void InitializeIfNeeded();
bool IsInitialized() const { return sensor_provider_.is_bound(); }
void OnSensorProviderConnectionError();
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
index 584ecf60106..ec5b6d73e63 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h"
#include "third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -114,10 +115,11 @@ bool SensorProxy::ShouldSuspendUpdates() const {
return true;
LocalFrame* focused_frame = GetPage()->GetFocusController().FocusedFrame();
- if (!focused_frame)
+ LocalFrame* this_frame = provider_->GetSupplementable()->GetFrame();
+
+ if (!focused_frame || !this_frame)
return true;
- LocalFrame* this_frame = provider_->GetSupplementable();
if (focused_frame == this_frame)
return false;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
index ac0329b8ba4..c4a435e9eef 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h
@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
index 67bb5840d19..f4bf5646020 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc
@@ -7,9 +7,9 @@
#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/serial/BUILD.gn b/chromium/third_party/blink/renderer/modules/serial/BUILD.gn
new file mode 100644
index 00000000000..f135be87463
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/BUILD.gn
@@ -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.
+
+import("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("serial") {
+ sources = [
+ "navigator_serial.cc",
+ "navigator_serial.h",
+ "serial.cc",
+ "serial.h",
+ "serial_port.cc",
+ "serial_port.h",
+ "worker_navigator_serial.cc",
+ "worker_navigator_serial.h",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
new file mode 100644
index 00000000000..e9f8bd406b4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.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 "third_party/blink/renderer/modules/serial/navigator_serial.h"
+
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/modules/serial/serial.h"
+
+namespace blink {
+
+const char NavigatorSerial::kSupplementName[] = "NavigatorSerial";
+
+NavigatorSerial& NavigatorSerial::From(Navigator& navigator) {
+ NavigatorSerial* supplement =
+ Supplement<Navigator>::From<NavigatorSerial>(navigator);
+ if (!supplement) {
+ supplement = new NavigatorSerial(navigator);
+ ProvideTo(navigator, supplement);
+ }
+ return *supplement;
+}
+
+Serial* NavigatorSerial::serial(Navigator& navigator) {
+ return NavigatorSerial::From(navigator).serial();
+}
+
+void NavigatorSerial::Trace(blink::Visitor* visitor) {
+ visitor->Trace(serial_);
+ Supplement<Navigator>::Trace(visitor);
+}
+
+NavigatorSerial::NavigatorSerial(Navigator& navigator)
+ : Supplement<Navigator>(navigator) {
+ if (navigator.GetFrame()) {
+ DCHECK(navigator.GetFrame()->GetDocument());
+ serial_ = Serial::Create(*navigator.GetFrame()->GetDocument());
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h
new file mode 100644
index 00000000000..7267c3597ec
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h
@@ -0,0 +1,38 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_NAVIGATOR_SERIAL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_NAVIGATOR_SERIAL_H_
+
+#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class Serial;
+
+class NavigatorSerial final : public GarbageCollected<NavigatorSerial>,
+ public Supplement<Navigator> {
+ USING_GARBAGE_COLLECTED_MIXIN(NavigatorSerial);
+
+ public:
+ static const char kSupplementName[];
+
+ static NavigatorSerial& From(Navigator&);
+
+ static Serial* serial(Navigator&);
+ Serial* serial() { return serial_; }
+
+ void Trace(Visitor*) override;
+
+ private:
+ explicit NavigatorSerial(Navigator&);
+
+ Member<Serial> serial_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_NAVIGATOR_SERIAL_H_
diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.idl b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.idl
new file mode 100644
index 00000000000..380dbca369c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.idl
@@ -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.
+
+// https://wicg.github.io/serial
+
+[
+ ImplementedAs=NavigatorSerial,
+ RuntimeEnabled=Serial,
+ SecureContext
+] partial interface Navigator {
+ [SameObject] readonly attribute Serial serial;
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.cc b/chromium/third_party/blink/renderer/modules/serial/serial.cc
new file mode 100644
index 00000000000..8c3a6407147
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/serial/serial.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/event_target_modules_names.h"
+
+namespace blink {
+
+// static
+Serial* Serial::Create(ExecutionContext& execution_context) {
+ return new Serial(execution_context);
+}
+
+ExecutionContext* Serial::GetExecutionContext() const {
+ return ContextLifecycleObserver::GetExecutionContext();
+}
+
+const AtomicString& Serial::InterfaceName() const {
+ return EventTargetNames::Serial;
+}
+
+ScriptPromise Serial::getPorts(ScriptState* script_state) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError));
+}
+
+ScriptPromise Serial::requestPort(ScriptState* script_state,
+ const SerialPortRequestOptions& options) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError));
+}
+
+void Serial::Trace(Visitor* visitor) {
+ EventTargetWithInlineData::Trace(visitor);
+ ContextLifecycleObserver::Trace(visitor);
+}
+
+Serial::Serial(ExecutionContext& execution_context)
+ : ContextLifecycleObserver(&execution_context) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.h b/chromium/third_party/blink/renderer/modules/serial/serial.h
new file mode 100644
index 00000000000..ead1ec0cbe5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.h
@@ -0,0 +1,46 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class ExecutionContext;
+class ScriptState;
+class SerialPortRequestOptions;
+
+class Serial final : public EventTargetWithInlineData,
+ public ContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(Serial);
+
+ public:
+ static Serial* Create(ExecutionContext& executionContext);
+
+ // EventTarget
+ ExecutionContext* GetExecutionContext() const override;
+ const AtomicString& InterfaceName() const override;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(connect);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect);
+ ScriptPromise getPorts(ScriptState*);
+ ScriptPromise requestPort(ScriptState*, const SerialPortRequestOptions&);
+
+ void Trace(Visitor*) override;
+
+ private:
+ explicit Serial(ExecutionContext&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_H_
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.idl b/chromium/third_party/blink/renderer/modules/serial/serial.idl
new file mode 100644
index 00000000000..b883b8e0939
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.idl
@@ -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.
+
+// https://wicg.github.io/serial
+
+[
+ Exposed(Window Serial,DedicatedWorker Serial),
+ SecureContext
+] interface Serial : EventTarget {
+ attribute EventHandler onconnect;
+ attribute EventHandler ondisconnect;
+
+ [CallWith=ScriptState, MeasureAs=SerialGetPorts]
+ Promise<sequence<SerialPort>> getPorts();
+
+ [CallWith=ScriptState, MeasureAs=SerialRequestPort, Exposed=Window]
+ Promise<SerialPort> requestPort(SerialPortRequestOptions options);
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_options.idl b/chromium/third_party/blink/renderer/modules/serial/serial_options.idl
new file mode 100644
index 00000000000..ccb1446965c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_options.idl
@@ -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.
+
+// https://wicg.github.io/serial
+
+enum ParityType {
+ "none",
+ "even",
+ "odd",
+};
+
+dictionary SerialOptions {
+ long baudrate = 9600;
+ octet databits = 8;
+ octet stopbits = 1;
+ ParityType parity = "none";
+ long buffersize = 255;
+ boolean rtscts = false;
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
new file mode 100644
index 00000000000..10739a4db1e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -0,0 +1,29 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/serial/serial_port.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+
+namespace blink {
+
+ScriptValue SerialPort::in(ScriptState* script_state) {
+ return ScriptValue::CreateNull(script_state);
+}
+
+ScriptValue SerialPort::out(ScriptState* script_state) {
+ return ScriptValue::CreateNull(script_state);
+}
+
+ScriptPromise SerialPort::open(ScriptState* script_state,
+ const SerialOptions& options) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError));
+}
+
+ScriptPromise SerialPort::close(ScriptState* script_state) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.h b/chromium/third_party/blink/renderer/modules/serial/serial_port.h
new file mode 100644
index 00000000000..baadd7b0601
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.h
@@ -0,0 +1,30 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class ScriptState;
+class SerialOptions;
+
+class SerialPort final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ ScriptValue in(ScriptState*);
+ ScriptValue out(ScriptState*);
+
+ ScriptPromise open(ScriptState*, const SerialOptions& options);
+ ScriptPromise close(ScriptState*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl
new file mode 100644
index 00000000000..794b9875eca
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl
@@ -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.
+
+// https://wicg.github.io/serial
+
+[
+ Exposed(Window Serial,DedicatedWorker Serial),
+ SecureContext
+] interface SerialPort {
+ // TODO(https://crbug.com/888165): "any" is used here because the IDL
+ // processor does not recognize ReadableStream or WritableStream when
+ // implemented with V8 extras.
+ [CallWith=ScriptState] readonly attribute any in;
+ [CallWith=ScriptState] readonly attribute any out;
+
+ [CallWith=ScriptState, MeasureAs=SerialPortOpen]
+ Promise<void> open(SerialOptions options);
+
+ [CallWith=ScriptState, MeasureAs=SerialPortClose]
+ Promise<void> close();
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
new file mode 100644
index 00000000000..8e9c05c5439
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://wicg.github.io/serial
+
+dictionary SerialPortRequestOptions {
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc
new file mode 100644
index 00000000000..a5a6b08694c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/serial/worker_navigator_serial.h"
+
+#include "third_party/blink/renderer/modules/serial/serial.h"
+
+namespace blink {
+
+const char WorkerNavigatorSerial::kSupplementName[] = "WorkerNavigatorSerial";
+
+WorkerNavigatorSerial& WorkerNavigatorSerial::From(WorkerNavigator& navigator) {
+ WorkerNavigatorSerial* supplement =
+ Supplement<WorkerNavigator>::From<WorkerNavigatorSerial>(navigator);
+ if (!supplement) {
+ supplement = new WorkerNavigatorSerial(navigator);
+ ProvideTo(navigator, supplement);
+ }
+ return *supplement;
+}
+
+Serial* WorkerNavigatorSerial::serial(ScriptState* script_state,
+ WorkerNavigator& navigator) {
+ return WorkerNavigatorSerial::From(navigator).serial(script_state);
+}
+
+Serial* WorkerNavigatorSerial::serial(ScriptState* script_state) {
+ if (!serial_) {
+ auto* execution_context = ExecutionContext::From(script_state);
+ DCHECK(execution_context);
+
+ // TODO(https://crbug.com/839117): Remove this check once the Exposed
+ // attribute is fixed to only expose this property in dedicated workers.
+ if (execution_context->IsDedicatedWorkerGlobalScope())
+ serial_ = Serial::Create(*execution_context);
+ }
+ return serial_;
+}
+
+void WorkerNavigatorSerial::Trace(blink::Visitor* visitor) {
+ visitor->Trace(serial_);
+ Supplement<WorkerNavigator>::Trace(visitor);
+}
+
+WorkerNavigatorSerial::WorkerNavigatorSerial(WorkerNavigator& navigator)
+ : Supplement<WorkerNavigator>(navigator) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h
new file mode 100644
index 00000000000..8ff078d3503
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.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 THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_WORKER_NAVIGATOR_SERIAL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_WORKER_NAVIGATOR_SERIAL_H_
+
+#include "third_party/blink/renderer/core/workers/worker_navigator.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class ScriptState;
+class Serial;
+
+class WorkerNavigatorSerial final
+ : public GarbageCollected<WorkerNavigatorSerial>,
+ public Supplement<WorkerNavigator> {
+ USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigatorSerial);
+
+ public:
+ static const char kSupplementName[];
+
+ static WorkerNavigatorSerial& From(WorkerNavigator&);
+
+ static Serial* serial(ScriptState*, WorkerNavigator&);
+ Serial* serial(ScriptState*);
+
+ void Trace(Visitor*) override;
+
+ private:
+ explicit WorkerNavigatorSerial(WorkerNavigator&);
+
+ Member<Serial> serial_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_WORKER_NAVIGATOR_SERIAL_H_
diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.idl b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.idl
new file mode 100644
index 00000000000..c95d2b0885f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.idl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/serial
+
+[
+ Exposed=DedicatedWorker,
+ ImplementedAs=WorkerNavigatorSerial,
+ RuntimeEnabled=Serial,
+ SecureContext
+] partial interface WorkerNavigator {
+ [CallWith=ScriptState, SameObject] readonly attribute Serial serial;
+};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn b/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
index 15340c6fc0b..fbe04fd2759 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
@@ -54,8 +54,8 @@ blink_modules_sources("service_worker") {
"service_worker_thread.h",
"service_worker_window_client.cc",
"service_worker_window_client.h",
- "service_worker_window_client_callback.cc",
- "service_worker_window_client_callback.h",
+ "thread_safe_script_container.cc",
+ "thread_safe_script_container.h",
"wait_until_observer.cc",
"wait_until_observer.h",
]
@@ -63,4 +63,8 @@ blink_modules_sources("service_worker") {
public_deps = [
"//third_party/blink/renderer/platform",
]
+
+ deps = [
+ "//base",
+ ]
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/DEPS b/chromium/third_party/blink/renderer/modules/service_worker/DEPS
index 2a04715c1b4..a6301afa47f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/DEPS
+++ b/chromium/third_party/blink/renderer/modules/service_worker/DEPS
@@ -1,4 +1,7 @@
include_rules = [
+ "+base/barrier_closure.h",
+ "+base/threading/thread_checker.h",
+ "+mojo/public/cpp/bindings/strong_binding.h",
"+mojo/public/cpp/system/data_pipe.h",
"+services/network/public/mojom",
"-third_party/blink/renderer/modules",
@@ -18,4 +21,11 @@ specific_include_rules = {
"+third_party/blink/renderer/modules/payments",
"+third_party/blink/renderer/modules/push_messaging",
],
+ "service_worker_installed_scripts_manager_test\.cc": [
+ "+base/run_loop.h",
+ "+mojo/public/cpp/bindings/binding.h",
+ ],
+ "web_embedded_worker_impl_test\.cc": [
+ "+third_party/blink/renderer/modules/exported",
+ ],
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
index a499d4c2239..b790caea27f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -10,7 +10,7 @@
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/fetch/bytes_consumer_for_data_consumer_handle.h"
+#include "third_party/blink/renderer/core/fetch/data_pipe_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
@@ -107,21 +107,22 @@ FetchEvent::~FetchEvent() = default;
void FetchEvent::OnNavigationPreloadResponse(
ScriptState* script_state,
std::unique_ptr<WebURLResponse> response,
- std::unique_ptr<WebDataConsumerHandle> data_consume_handle) {
+ mojo::ScopedDataPipeConsumerHandle data_pipe) {
if (!script_state->ContextIsValid())
return;
DCHECK(preload_response_property_);
DCHECK(!preload_response_);
ScriptState::Scope scope(script_state);
preload_response_ = std::move(response);
+ if (data_pipe.is_valid()) {
+ data_pipe_consumer_ = new DataPipeBytesConsumer(
+ ExecutionContext::From(script_state), std::move(data_pipe));
+ }
// TODO(ricea): Verify that this response can't be aborted from JS.
FetchResponseData* response_data =
- data_consume_handle
+ data_pipe_consumer_
? FetchResponseData::CreateWithBuffer(new BodyStreamBuffer(
- script_state,
- new BytesConsumerForDataConsumerHandle(
- ExecutionContext::From(script_state),
- std::move(data_consume_handle)),
+ script_state, data_pipe_consumer_,
new AbortSignal(ExecutionContext::From(script_state))))
: FetchResponseData::Create();
Vector<KURL> url_list(1);
@@ -149,6 +150,10 @@ void FetchEvent::OnNavigationPreloadError(
std::unique_ptr<WebServiceWorkerError> error) {
if (!script_state->ContextIsValid())
return;
+ if (data_pipe_consumer_) {
+ data_pipe_consumer_->SignalError();
+ data_pipe_consumer_ = nullptr;
+ }
DCHECK(preload_response_property_);
if (preload_response_property_->GetState() !=
PreloadResponseProperty::kPending) {
@@ -165,6 +170,10 @@ void FetchEvent::OnNavigationPreloadComplete(
int64_t encoded_body_length,
int64_t decoded_body_length) {
DCHECK(preload_response_);
+ if (data_pipe_consumer_) {
+ data_pipe_consumer_->SignalComplete();
+ data_pipe_consumer_ = nullptr;
+ }
std::unique_ptr<WebURLResponse> response = std::move(preload_response_);
ResourceResponse resource_response = response->ToResourceResponse();
resource_response.SetEncodedDataLength(encoded_data_length);
@@ -188,6 +197,7 @@ void FetchEvent::Trace(blink::Visitor* visitor) {
visitor->Trace(observer_);
visitor->Trace(request_);
visitor->Trace(preload_response_property_);
+ visitor->Trace(data_pipe_consumer_);
ExtendableEvent::Trace(visitor);
ContextClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
index 1bf70d4484b..5482c436e63 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
@@ -22,12 +22,12 @@
namespace blink {
+class DataPipeBytesConsumer;
class ExceptionState;
class FetchRespondWithObserver;
class Request;
class Response;
class ScriptState;
-class WebDataConsumerHandle;
struct WebServiceWorkerError;
class WebURLResponse;
class WorkerGlobalScope;
@@ -67,7 +67,7 @@ class MODULES_EXPORT FetchEvent final
void OnNavigationPreloadResponse(ScriptState*,
std::unique_ptr<WebURLResponse>,
- std::unique_ptr<WebDataConsumerHandle>);
+ mojo::ScopedDataPipeConsumerHandle);
void OnNavigationPreloadError(ScriptState*,
std::unique_ptr<WebServiceWorkerError>);
void OnNavigationPreloadComplete(WorkerGlobalScope*,
@@ -96,6 +96,7 @@ class MODULES_EXPORT FetchEvent final
TraceWrapperMember<Request> request_;
Member<PreloadResponseProperty> preload_response_property_;
std::unique_ptr<WebURLResponse> preload_response_;
+ Member<DataPipeBytesConsumer> data_pipe_consumer_;
String client_id_;
bool is_reload_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
index 2aabdee38fb..7860b3bc2a4 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -7,6 +7,8 @@
#include <memory>
#include <utility>
+#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
@@ -112,10 +114,10 @@ bool IsNavigationRequest(network::mojom::RequestContextFrameType frame_type) {
}
bool IsClientRequest(network::mojom::RequestContextFrameType frame_type,
- WebURLRequest::RequestContext request_context) {
+ mojom::RequestContextType request_context) {
return IsNavigationRequest(frame_type) ||
- request_context == WebURLRequest::kRequestContextSharedWorker ||
- request_context == WebURLRequest::kRequestContextWorker;
+ request_context == mojom::RequestContextType::SHARED_WORKER ||
+ request_context == mojom::RequestContextType::WORKER;
}
// Notifies the result of FetchDataLoader to |handle_|. |handle_| pass through
@@ -127,25 +129,67 @@ class FetchLoaderClient final
USING_GARBAGE_COLLECTED_MIXIN(FetchLoaderClient);
public:
- explicit FetchLoaderClient(
- std::unique_ptr<WebServiceWorkerStreamHandle> handle)
- : handle_(std::move(handle)) {}
+ FetchLoaderClient() {}
- void DidFetchDataLoadedDataPipe() override { handle_->Completed(); }
- void DidFetchDataLoadFailed() override { handle_->Aborted(); }
+ void DidFetchDataStartedDataPipe(
+ mojo::ScopedDataPipeConsumerHandle pipe) override {
+ DCHECK(!handle_);
+ handle_ = std::make_unique<WebServiceWorkerStreamHandle>(std::move(pipe));
+ }
+ void DidFetchDataLoadedDataPipe() override {
+ DCHECK(handle_);
+ // If this method is called synchronously from StartLoading() then we need
+ // to delay notifying the handle until after
+ // RespondToFetchEventWithResponseStream() is called.
+ if (!started_) {
+ pending_complete_ = true;
+ return;
+ }
+ pending_complete_ = false;
+ handle_->Completed();
+ }
+ void DidFetchDataLoadFailed() override {
+ // If this method is called synchronously from StartLoading() then we need
+ // to delay notifying the handle until after
+ // RespondToFetchEventWithResponseStream() is called.
+ if (!started_) {
+ pending_failure_ = true;
+ return;
+ }
+ pending_failure_ = false;
+ if (handle_)
+ handle_->Aborted();
+ }
void Abort() override {
// A fetch() aborted via AbortSignal in the ServiceWorker will just look
// like an ordinary failure to the page.
// TODO(ricea): Should a fetch() on the page get an AbortError instead?
- handle_->Aborted();
+ if (handle_)
+ handle_->Aborted();
+ }
+
+ void SetStarted() {
+ DCHECK(!started_);
+ // Note that RespondToFetchEventWithResponseStream() has been called and
+ // flush any pending operation.
+ started_ = true;
+ if (pending_complete_)
+ DidFetchDataLoadedDataPipe();
+ else if (pending_failure_)
+ DidFetchDataLoadFailed();
}
+ WebServiceWorkerStreamHandle* Handle() const { return handle_.get(); }
+
void Trace(blink::Visitor* visitor) override {
FetchDataLoader::Client::Trace(visitor);
}
private:
std::unique_ptr<WebServiceWorkerStreamHandle> handle_;
+ bool started_ = false;
+ bool pending_complete_ = false;
+ bool pending_failure_ = false;
};
} // namespace
@@ -157,7 +201,7 @@ FetchRespondWithObserver* FetchRespondWithObserver::Create(
network::mojom::FetchRequestMode request_mode,
network::mojom::FetchRedirectMode redirect_mode,
network::mojom::RequestContextFrameType frame_type,
- WebURLRequest::RequestContext request_context,
+ mojom::RequestContextType request_context,
WaitUntilObserver* observer) {
return new FetchRespondWithObserver(context, fetch_event_id, request_url,
request_mode, redirect_mode, frame_type,
@@ -179,7 +223,8 @@ void FetchRespondWithObserver::OnResponseRejected(
WebServiceWorkerResponse web_response;
web_response.SetError(error);
ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
- ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_);
+ ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_,
+ base::TimeTicks::Now());
}
void FetchRespondWithObserver::OnResponseFulfilled(
@@ -283,44 +328,45 @@ void FetchRespondWithObserver::OnResponseFulfilled(
// Handle the blob response body.
web_response.SetBlobDataHandle(blob_data_handle);
ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
- ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_);
+ ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_,
+ base::TimeTicks::Now());
return;
}
- // Handle the stream response body.
- mojo::ScopedDataPipeProducerHandle producer;
- mojo::ScopedDataPipeConsumerHandle consumer;
- MojoResult result = mojo::CreateDataPipe(nullptr, &producer, &consumer);
- if (result != MOJO_RESULT_OK) {
- OnResponseRejected(ServiceWorkerResponseError::kDataPipeCreationFailed);
- return;
- }
- DCHECK(producer.is_valid());
- DCHECK(consumer.is_valid());
- std::unique_ptr<WebServiceWorkerStreamHandle> body_stream_handle =
- std::make_unique<WebServiceWorkerStreamHandle>(std::move(consumer));
- ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
- ->RespondToFetchEventWithResponseStream(event_id_, web_response,
- body_stream_handle.get(),
- event_dispatch_time_);
-
- buffer->StartLoading(FetchDataLoader::CreateLoaderAsDataPipe(
- std::move(producer), task_runner_),
- new FetchLoaderClient(std::move(body_stream_handle)),
- exception_state);
+ // Load the Response as a mojo::DataPipe. The resulting pipe consumer
+ // handle will be passed to the FetchLoaderClient on start.
+ FetchLoaderClient* fetch_loader_client = new FetchLoaderClient();
+ buffer->StartLoading(FetchDataLoader::CreateLoaderAsDataPipe(task_runner_),
+ fetch_loader_client, exception_state);
if (exception_state.HadException()) {
OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken);
return;
}
+
+ // If we failed to create the WebServiceWorkerStreamHandle then we must
+ // have failed to allocate the mojo::DataPipe.
+ if (!fetch_loader_client->Handle()) {
+ OnResponseRejected(ServiceWorkerResponseError::kDataPipeCreationFailed);
+ return;
+ }
+
+ ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
+ ->RespondToFetchEventWithResponseStream(
+ event_id_, web_response, fetch_loader_client->Handle(),
+ event_dispatch_time_, base::TimeTicks::Now());
+
+ fetch_loader_client->SetStarted();
return;
}
ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
- ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_);
+ ->RespondToFetchEvent(event_id_, web_response, event_dispatch_time_,
+ base::TimeTicks::Now());
}
void FetchRespondWithObserver::OnNoResponse() {
ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
- ->RespondToFetchEventWithNoResponse(event_id_, event_dispatch_time_);
+ ->RespondToFetchEventWithNoResponse(event_id_, event_dispatch_time_,
+ base::TimeTicks::Now());
}
FetchRespondWithObserver::FetchRespondWithObserver(
@@ -330,7 +376,7 @@ FetchRespondWithObserver::FetchRespondWithObserver(
network::mojom::FetchRequestMode request_mode,
network::mojom::FetchRedirectMode redirect_mode,
network::mojom::RequestContextFrameType frame_type,
- WebURLRequest::RequestContext request_context,
+ mojom::RequestContextType request_context,
WaitUntilObserver* observer)
: RespondWithObserver(context, fetch_event_id, observer),
request_url_(request_url),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
index 394d7e066ad..892927e5aa4 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h
@@ -31,7 +31,7 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
network::mojom::FetchRequestMode,
network::mojom::FetchRedirectMode,
network::mojom::RequestContextFrameType,
- WebURLRequest::RequestContext,
+ mojom::RequestContextType,
WaitUntilObserver*);
void OnResponseRejected(mojom::ServiceWorkerResponseError) override;
@@ -50,7 +50,7 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
network::mojom::FetchRequestMode,
network::mojom::FetchRedirectMode,
network::mojom::RequestContextFrameType,
- WebURLRequest::RequestContext,
+ mojom::RequestContextType,
WaitUntilObserver*);
private:
@@ -58,7 +58,7 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
const network::mojom::FetchRequestMode request_mode_;
const network::mojom::FetchRedirectMode redirect_mode_;
const network::mojom::RequestContextFrameType frame_type_;
- const WebURLRequest::RequestContext request_context_;
+ const mojom::RequestContextType request_context_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/registration_options.idl b/chromium/third_party/blink/renderer/modules/service_worker/registration_options.idl
index 4442ea6b261..3730e774f16 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/registration_options.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/registration_options.idl
@@ -5,5 +5,6 @@
// https://w3c.github.io/ServiceWorker/#dictdef-registrationoptions
dictionary RegistrationOptions {
USVString scope;
+ WorkerType type = "classic";
ServiceWorkerUpdateViaCache updateViaCache = "imports";
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
index 564b748a583..216334f6947 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
@@ -27,7 +27,7 @@ void RespondWithObserver::ContextDestroyed(ExecutionContext*) {
}
void RespondWithObserver::WillDispatchEvent() {
- event_dispatch_time_ = WTF::CurrentTime();
+ event_dispatch_time_ = WTF::CurrentTimeTicks();
}
void RespondWithObserver::DidDispatchEvent(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
index ed0547e7ec3..8b03e7f0d53 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
@@ -59,7 +59,7 @@ class MODULES_EXPORT RespondWithObserver
protected:
RespondWithObserver(ExecutionContext*, int event_id, WaitUntilObserver*);
const int event_id_;
- double event_dispatch_time_ = 0;
+ TimeTicks event_dispatch_time_;
private:
class ThenFunction;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 20ff71cf4f4..e16880a2b11 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
@@ -33,7 +33,7 @@
#include <memory>
#include "third_party/blink/public/mojom/service_worker/service_worker_state.mojom-blink.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_container_client.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -65,9 +66,7 @@ void ServiceWorker::postMessage(ScriptState* script_state,
const ScriptValue& message,
const PostMessageOptions& options,
ExceptionState& exception_state) {
- ServiceWorkerContainerClient* client =
- ServiceWorkerContainerClient::From(GetExecutionContext());
- if (!client || !client->Provider()) {
+ if (!GetExecutionContext()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"Failed to post a message: No associated provider is available.");
@@ -92,35 +91,35 @@ void ServiceWorker::postMessage(ScriptState* script_state,
if (exception_state.HadException())
return;
- if (handle_->ServiceWorker()->GetState() ==
- mojom::blink::ServiceWorkerState::kRedundant) {
+ if (state_ == mojom::blink::ServiceWorkerState::kRedundant) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"ServiceWorker is in redundant state.");
return;
}
- handle_->ServiceWorker()->PostMessageToServiceWorker(
- ToTransferableMessage(std::move(msg)));
+ host_->PostMessageToServiceWorker(std::move(msg));
}
ScriptPromise ServiceWorker::InternalsTerminate(ScriptState* script_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
- handle_->ServiceWorker()->TerminateForTesting(
- std::make_unique<CallbackPromiseAdapter<void, void>>(resolver));
+ host_->TerminateForTesting(
+ WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); },
+ WrapPersistent(resolver)));
return promise;
}
-void ServiceWorker::DispatchStateChangeEvent() {
+void ServiceWorker::StateChanged(mojom::blink::ServiceWorkerState new_state) {
+ state_ = new_state;
this->DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
String ServiceWorker::scriptURL() const {
- return handle_->ServiceWorker()->Url().GetString();
+ return url_.GetString();
}
String ServiceWorker::state() const {
- switch (handle_->ServiceWorker()->GetState()) {
+ switch (state_) {
case mojom::blink::ServiceWorkerState::kUnknown:
// The web platform should never see this internal state
NOTREACHED();
@@ -140,46 +139,45 @@ String ServiceWorker::state() const {
return g_null_atom;
}
-ServiceWorker* ServiceWorker::From(
- ExecutionContext* execution_context,
- std::unique_ptr<WebServiceWorker::Handle> handle) {
- return GetOrCreate(execution_context, std::move(handle));
+ServiceWorker* ServiceWorker::From(ExecutionContext* context,
+ WebServiceWorkerObjectInfo info) {
+ if (!context)
+ return nullptr;
+ if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId)
+ return nullptr;
+
+ if (context->IsServiceWorkerGlobalScope()) {
+ return ToServiceWorkerGlobalScope(context)->GetOrCreateServiceWorker(
+ std::move(info));
+ }
+
+ return ServiceWorkerContainerClient::From(To<Document>(context))
+ ->GetOrCreateServiceWorker(std::move(info));
}
bool ServiceWorker::HasPendingActivity() const {
if (was_stopped_)
return false;
- return handle_->ServiceWorker()->GetState() !=
- mojom::blink::ServiceWorkerState::kRedundant;
+ return state_ != mojom::blink::ServiceWorkerState::kRedundant;
}
void ServiceWorker::ContextDestroyed(ExecutionContext*) {
was_stopped_ = true;
}
-ServiceWorker* ServiceWorker::GetOrCreate(
- ExecutionContext* execution_context,
- std::unique_ptr<WebServiceWorker::Handle> handle) {
- if (!handle)
- return nullptr;
-
- ServiceWorker* existing_worker =
- static_cast<ServiceWorker*>(handle->ServiceWorker()->Proxy());
- if (existing_worker) {
- DCHECK_EQ(existing_worker->GetExecutionContext(), execution_context);
- return existing_worker;
- }
-
- return new ServiceWorker(execution_context, std::move(handle));
-}
-
ServiceWorker::ServiceWorker(ExecutionContext* execution_context,
- std::unique_ptr<WebServiceWorker::Handle> handle)
+ WebServiceWorkerObjectInfo info)
: AbstractWorker(execution_context),
- handle_(std::move(handle)),
- was_stopped_(false) {
- DCHECK(handle_);
- handle_->ServiceWorker()->SetProxy(this);
+ was_stopped_(false),
+ url_(info.url),
+ state_(info.state),
+ binding_(this) {
+ DCHECK_NE(mojom::blink::kInvalidServiceWorkerVersionId, info.version_id);
+ host_.Bind(mojom::blink::ServiceWorkerObjectHostAssociatedPtrInfo(
+ std::move(info.host_ptr_info),
+ mojom::blink::ServiceWorkerObjectHost::Version_));
+ binding_.Bind(mojom::blink::ServiceWorkerObjectAssociatedRequest(
+ std::move(info.request)));
}
ServiceWorker::~ServiceWorker() = default;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
index be575e131f5..f6d3cb7b5ff 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h
@@ -33,8 +33,9 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_proxy.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_object_info.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
@@ -49,14 +50,14 @@ class ScriptState;
class MODULES_EXPORT ServiceWorker final
: public AbstractWorker,
public ActiveScriptWrappable<ServiceWorker>,
- public WebServiceWorkerProxy {
+ public mojom::blink::ServiceWorkerObject {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ServiceWorker);
public:
- static ServiceWorker* From(ExecutionContext*,
- std::unique_ptr<WebServiceWorker::Handle>);
+ static ServiceWorker* From(ExecutionContext*, WebServiceWorkerObjectInfo);
+ ServiceWorker(ExecutionContext*, WebServiceWorkerObjectInfo);
~ServiceWorker() override;
void Trace(blink::Visitor*) override;
@@ -81,25 +82,33 @@ class MODULES_EXPORT ServiceWorker final
// ScriptWrappable overrides.
bool HasPendingActivity() const final;
- // WebServiceWorkerProxy overrides.
- void DispatchStateChangeEvent() override;
-
// AbstractWorker overrides.
const AtomicString& InterfaceName() const override;
+ // Implements mojom::blink::ServiceWorkerObject.
+ void StateChanged(mojom::blink::ServiceWorkerState new_state) override;
+
ScriptPromise InternalsTerminate(ScriptState*);
private:
- static ServiceWorker* GetOrCreate(ExecutionContext*,
- std::unique_ptr<WebServiceWorker::Handle>);
- ServiceWorker(ExecutionContext*, std::unique_ptr<WebServiceWorker::Handle>);
-
// PausableObject overrides.
void ContextDestroyed(ExecutionContext*) override;
- // A handle to the service worker representation in the embedder.
- std::unique_ptr<WebServiceWorker::Handle> handle_;
bool was_stopped_;
+ const KURL url_;
+ mojom::blink::ServiceWorkerState state_;
+ // Both |host_| and |binding_| are associated with
+ // content.mojom.ServiceWorkerContainer interface for a Document, and
+ // content.mojom.ServiceWorker interface for a ServiceWorkerGlobalScope.
+ //
+ // |host_| keeps the Mojo connection to the
+ // browser-side ServiceWorkerObjectHost, whose lifetime is bound
+ // to |host_| via the Mojo connection.
+ mojom::blink::ServiceWorkerObjectHostAssociatedPtr host_;
+ // |binding_| keeps the Mojo binding to serve its other Mojo endpoint (i.e.
+ // the caller end) held by the content::ServiceWorkerObjectHost in the browser
+ // process.
+ mojo::AssociatedBinding<mojom::blink::ServiceWorkerObject> binding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
index 959f27b1a02..a6c32d2b03b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
@@ -8,7 +8,6 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
@@ -22,27 +21,13 @@
namespace blink {
-ServiceWorkerClient* ServiceWorkerClient::Take(
- ScriptPromiseResolver*,
- std::unique_ptr<WebServiceWorkerClientInfo> web_client) {
- if (!web_client)
- return nullptr;
-
- switch (web_client->client_type) {
- case mojom::ServiceWorkerClientType::kWindow:
- return ServiceWorkerWindowClient::Create(*web_client);
- case mojom::ServiceWorkerClientType::kSharedWorker:
- return ServiceWorkerClient::Create(*web_client);
- case mojom::ServiceWorkerClientType::kAll:
- NOTREACHED();
- return nullptr;
- }
- NOTREACHED();
- return nullptr;
+ServiceWorkerClient* ServiceWorkerClient::Create(
+ const WebServiceWorkerClientInfo& info) {
+ return new ServiceWorkerClient(info);
}
ServiceWorkerClient* ServiceWorkerClient::Create(
- const WebServiceWorkerClientInfo& info) {
+ const mojom::blink::ServiceWorkerClientInfo& info) {
return new ServiceWorkerClient(info);
}
@@ -52,6 +37,13 @@ ServiceWorkerClient::ServiceWorkerClient(const WebServiceWorkerClientInfo& info)
type_(info.client_type),
frame_type_(info.frame_type) {}
+ServiceWorkerClient::ServiceWorkerClient(
+ const mojom::blink::ServiceWorkerClientInfo& info)
+ : uuid_(info.client_uuid),
+ url_(info.url.GetString()),
+ type_(info.client_type),
+ frame_type_(info.frame_type) {}
+
ServiceWorkerClient::~ServiceWorkerClient() = default;
String ServiceWorkerClient::type() const {
@@ -120,7 +112,7 @@ void ServiceWorkerClient::postMessage(ScriptState* script_state,
return;
ServiceWorkerGlobalScopeClient::From(context)->PostMessageToClient(
- uuid_, ToTransferableMessage(std::move(msg)));
+ uuid_, std::move(msg));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
index 8dc40463664..e6c44cb9762 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_CLIENT_H_
#include <memory>
+#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -16,19 +17,15 @@
namespace blink {
class PostMessageOptions;
-class ScriptPromiseResolver;
class ScriptState;
class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- // To be used by CallbackPromiseAdapter.
- using WebType = std::unique_ptr<WebServiceWorkerClientInfo>;
-
- static ServiceWorkerClient* Take(ScriptPromiseResolver*,
- std::unique_ptr<WebServiceWorkerClientInfo>);
static ServiceWorkerClient* Create(const WebServiceWorkerClientInfo&);
+ static ServiceWorkerClient* Create(
+ const mojom::blink::ServiceWorkerClientInfo&);
~ServiceWorkerClient() override;
@@ -48,6 +45,7 @@ class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable {
protected:
explicit ServiceWorkerClient(const WebServiceWorkerClientInfo&);
+ explicit ServiceWorkerClient(const mojom::blink::ServiceWorkerClientInfo&);
String Uuid() const { return uuid_; }
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
index d717f2161ac..af1a97e11d5 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
@@ -7,10 +7,10 @@
#include <memory>
#include <utility>
+#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_client_query_options.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -21,7 +21,6 @@
#include "third_party/blink/renderer/modules/service_worker/service_worker_error.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -29,28 +28,6 @@ namespace blink {
namespace {
-class ClientArray {
- public:
- using WebType = const WebServiceWorkerClientsInfo&;
- static HeapVector<Member<ServiceWorkerClient>> Take(
- ScriptPromiseResolver*,
- const WebServiceWorkerClientsInfo& web_clients) {
- HeapVector<Member<ServiceWorkerClient>> clients;
- for (size_t i = 0; i < web_clients.clients.size(); ++i) {
- const WebServiceWorkerClientInfo& client = web_clients.clients[i];
- if (client.client_type == mojom::ServiceWorkerClientType::kWindow)
- clients.push_back(ServiceWorkerWindowClient::Create(client));
- else
- clients.push_back(ServiceWorkerClient::Create(client));
- }
- return clients;
- }
-
- private:
- WTF_MAKE_NONCOPYABLE(ClientArray);
- ClientArray() = delete;
-};
-
mojom::ServiceWorkerClientType GetClientType(const String& type) {
if (type == "window")
return mojom::ServiceWorkerClientType::kWindow;
@@ -62,37 +39,67 @@ mojom::ServiceWorkerClientType GetClientType(const String& type) {
return mojom::ServiceWorkerClientType::kWindow;
}
-class GetCallback : public WebServiceWorkerClientCallbacks {
- public:
- explicit GetCallback(ScriptPromiseResolver* resolver) : resolver_(resolver) {}
- ~GetCallback() override = default;
-
- void OnSuccess(
- std::unique_ptr<WebServiceWorkerClientInfo> web_client) override {
- std::unique_ptr<WebServiceWorkerClientInfo> client =
- base::WrapUnique(web_client.release());
- if (!resolver_->GetExecutionContext() ||
- resolver_->GetExecutionContext()->IsContextDestroyed())
- return;
- if (!client) {
- // Resolve the promise with undefined.
- resolver_->Resolve();
- return;
- }
- resolver_->Resolve(ServiceWorkerClient::Take(resolver_, std::move(client)));
+void DidGetClient(ScriptPromiseResolver* resolver,
+ mojom::blink::ServiceWorkerClientInfoPtr info) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
}
- void OnError(const WebServiceWorkerError& error) override {
- if (!resolver_->GetExecutionContext() ||
- resolver_->GetExecutionContext()->IsContextDestroyed())
+ if (!info) {
+ // Resolve the promise with undefined.
+ resolver->Resolve();
+ return;
+ }
+ ServiceWorkerClient* client = nullptr;
+ switch (info->client_type) {
+ case mojom::ServiceWorkerClientType::kWindow:
+ client = ServiceWorkerWindowClient::Create(*info);
+ break;
+ case mojom::ServiceWorkerClientType::kSharedWorker:
+ client = ServiceWorkerClient::Create(*info);
+ break;
+ case mojom::ServiceWorkerClientType::kAll:
+ NOTREACHED();
return;
- resolver_->Reject(ServiceWorkerError::Take(resolver_.Get(), error));
}
+ resolver->Resolve(client);
+}
- private:
- Persistent<ScriptPromiseResolver> resolver_;
- WTF_MAKE_NONCOPYABLE(GetCallback);
-};
+void DidClaim(ScriptPromiseResolver* resolver,
+ mojom::blink::ServiceWorkerErrorType error,
+ const String& error_msg) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
+ }
+
+ if (error != mojom::blink::ServiceWorkerErrorType::kNone) {
+ DCHECK(!error_msg.IsNull());
+ resolver->Reject(
+ ServiceWorkerError::GetException(resolver, error, error_msg));
+ return;
+ }
+ DCHECK(error_msg.IsNull());
+ resolver->Resolve();
+}
+
+void DidGetClients(ScriptPromiseResolver* resolver,
+ Vector<mojom::blink::ServiceWorkerClientInfoPtr> infos) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
+ }
+
+ HeapVector<Member<ServiceWorkerClient>> clients;
+ for (const auto& info : infos) {
+ if (info->client_type == mojom::blink::ServiceWorkerClientType::kWindow)
+ clients.push_back(ServiceWorkerWindowClient::Create(*info));
+ else
+ clients.push_back(ServiceWorkerClient::Create(*info));
+ }
+ resolver->Resolve(std::move(clients));
+}
} // namespace
@@ -111,11 +118,9 @@ ScriptPromise ServiceWorkerClients::get(ScriptState* script_state,
return ScriptPromise();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
ServiceWorkerGlobalScopeClient::From(execution_context)
- ->GetClient(id, std::make_unique<GetCallback>(resolver));
- return promise;
+ ->GetClient(id, WTF::Bind(&DidGetClient, WrapPersistent(resolver)));
+ return resolver->Promise();
}
ScriptPromise ServiceWorkerClients::matchAll(
@@ -127,17 +132,12 @@ ScriptPromise ServiceWorkerClients::matchAll(
return ScriptPromise();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- WebServiceWorkerClientQueryOptions web_options;
- web_options.client_type = GetClientType(options.type());
- web_options.include_uncontrolled = options.includeUncontrolled();
ServiceWorkerGlobalScopeClient::From(execution_context)
- ->GetClients(web_options,
- std::make_unique<
- CallbackPromiseAdapter<ClientArray, ServiceWorkerError>>(
- resolver));
- return promise;
+ ->GetClients(
+ mojom::blink::ServiceWorkerClientQueryOptions::New(
+ options.includeUncontrolled(), GetClientType(options.type())),
+ WTF::Bind(&DidGetClients, WrapPersistent(resolver)));
+ return resolver->Promise();
}
ScriptPromise ServiceWorkerClients::claim(ScriptState* script_state) {
@@ -148,14 +148,9 @@ ScriptPromise ServiceWorkerClients::claim(ScriptState* script_state) {
return ScriptPromise();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- auto callbacks =
- std::make_unique<CallbackPromiseAdapter<void, ServiceWorkerError>>(
- resolver);
ServiceWorkerGlobalScopeClient::From(execution_context)
- ->Claim(std::move(callbacks));
- return promise;
+ ->Claim(WTF::Bind(&DidClaim, WrapPersistent(resolver)));
+ return resolver->Promise();
}
ScriptPromise ServiceWorkerClients::openWindow(ScriptState* script_state,
@@ -186,7 +181,7 @@ ScriptPromise ServiceWorkerClients::openWindow(ScriptState* script_state,
context->ConsumeWindowInteraction();
ServiceWorkerGlobalScopeClient::From(context)->OpenWindowForClients(
- parsed_url, std::make_unique<NavigateClientCallback>(resolver));
+ parsed_url, resolver);
return promise;
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index b86eca316ed..3ef322ab040 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -31,8 +31,9 @@
#include <memory>
#include <utility>
+
+#include "base/macros.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -50,6 +51,7 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -78,6 +80,15 @@ mojom::ServiceWorkerUpdateViaCache ParseUpdateViaCache(const String& value) {
return mojom::ServiceWorkerUpdateViaCache::kImports;
}
+mojom::ScriptType ParseScriptType(const String& type) {
+ if (type == "classic")
+ return mojom::ScriptType::kClassic;
+ if (type == "module")
+ return mojom::ScriptType::kModule;
+ NOTREACHED() << "Invalid type: " << type;
+ return mojom::ScriptType::kClassic;
+}
+
class GetRegistrationCallback : public WebServiceWorkerProvider::
WebServiceWorkerGetRegistrationCallbacks {
public:
@@ -108,7 +119,7 @@ class GetRegistrationCallback : public WebServiceWorkerProvider::
private:
Persistent<ScriptPromiseResolver> resolver_;
- WTF_MAKE_NONCOPYABLE(GetRegistrationCallback);
+ DISALLOW_COPY_AND_ASSIGN(GetRegistrationCallback);
};
} // namespace
@@ -134,7 +145,7 @@ class ServiceWorkerContainer::GetRegistrationForReadyCallback
private:
Persistent<ReadyProperty> ready_;
- WTF_MAKE_NONCOPYABLE(GetRegistrationForReadyCallback);
+ DISALLOW_COPY_AND_ASSIGN(GetRegistrationForReadyCallback);
};
ServiceWorkerContainer* ServiceWorkerContainer::Create(
@@ -179,6 +190,17 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
return promise;
}
+ // TODO(asamidoi): Remove this check after module loading for
+ // ServiceWorker is enabled by default (https://crbug.com/824647).
+ if (options.type() == "module" &&
+ !RuntimeEnabledFeatures::ModuleServiceWorkerEnabled()) {
+ resolver->Reject(DOMException::Create(
+ DOMExceptionCode::kNotSupportedError,
+ "type 'module' in RegistrationOptions is not implemented yet."
+ "See https://crbug.com/824647 for details."));
+ return promise;
+ }
+
auto callbacks = std::make_unique<CallbackPromiseAdapter<
ServiceWorkerRegistration, ServiceWorkerErrorForUpdate>>(resolver);
@@ -268,7 +290,7 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
ContentSecurityPolicy* csp = execution_context->GetContentSecurityPolicy();
if (csp) {
if (!csp->AllowRequestWithoutIntegrity(
- WebURLRequest::kRequestContextServiceWorker, script_url) ||
+ mojom::RequestContextType::SERVICE_WORKER, script_url) ||
!csp->AllowWorkerContextFromSource(
script_url, ResourceRequest::RedirectStatus::kNoRedirect,
SecurityViolationReportingPolicy::kReport)) {
@@ -284,9 +306,10 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
mojom::ServiceWorkerUpdateViaCache update_via_cache =
ParseUpdateViaCache(options.updateViaCache());
+ mojom::ScriptType type = ParseScriptType(options.type());
- provider_->RegisterServiceWorker(pattern_url, script_url, update_via_cache,
- std::move(callbacks));
+ provider_->RegisterServiceWorker(pattern_url, script_url, type,
+ update_via_cache, std::move(callbacks));
return promise;
}
@@ -382,11 +405,6 @@ ScriptPromise ServiceWorkerContainer::getRegistrations(
return promise;
}
-ServiceWorkerContainer::ReadyProperty*
-ServiceWorkerContainer::CreateReadyProperty() {
- return new ReadyProperty(GetExecutionContext(), this, ReadyProperty::kReady);
-}
-
ScriptPromise ServiceWorkerContainer::ready(ScriptState* caller_state) {
if (!GetExecutionContext())
return ScriptPromise();
@@ -412,11 +430,11 @@ ScriptPromise ServiceWorkerContainer::ready(ScriptState* caller_state) {
}
void ServiceWorkerContainer::SetController(
- std::unique_ptr<WebServiceWorker::Handle> handle,
+ WebServiceWorkerObjectInfo info,
bool should_notify_controller_change) {
if (!GetExecutionContext())
return;
- controller_ = ServiceWorker::From(GetExecutionContext(), std::move(handle));
+ controller_ = ServiceWorker::From(GetExecutionContext(), std::move(info));
if (controller_) {
UseCounter::Count(GetExecutionContext(),
WebFeature::kServiceWorkerControlledPage);
@@ -426,7 +444,7 @@ void ServiceWorkerContainer::SetController(
}
void ServiceWorkerContainer::DispatchMessageEvent(
- std::unique_ptr<WebServiceWorker::Handle> handle,
+ WebServiceWorkerObjectInfo info,
TransferableMessage message) {
if (!GetExecutionContext() || !GetExecutionContext()->ExecutingWindow())
return;
@@ -434,7 +452,7 @@ void ServiceWorkerContainer::DispatchMessageEvent(
MessagePortArray* ports =
MessagePort::EntanglePorts(*GetExecutionContext(), std::move(msg.ports));
ServiceWorker* source =
- ServiceWorker::From(GetExecutionContext(), std::move(handle));
+ ServiceWorker::From(GetExecutionContext(), std::move(info));
MessageEvent* event;
if (!msg.locked_agent_cluster_id ||
GetExecutionContext()->IsSameAgentCluster(*msg.locked_agent_cluster_id)) {
@@ -472,11 +490,16 @@ ServiceWorkerContainer::ServiceWorkerContainer(
return;
if (ServiceWorkerContainerClient* client =
- ServiceWorkerContainerClient::From(execution_context)) {
+ ServiceWorkerContainerClient::From(To<Document>(execution_context))) {
provider_ = client->Provider();
if (provider_)
provider_->SetClient(this);
}
}
+ServiceWorkerContainer::ReadyProperty*
+ServiceWorkerContainer::CreateReadyProperty() {
+ return new ReadyProperty(GetExecutionContext(), this, ReadyProperty::kReady);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
index ea5bc3e4f53..d45a9db839d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
@@ -51,7 +51,6 @@ namespace blink {
class ExecutionContext;
class NavigatorServiceWorker;
-class WebServiceWorker;
class WebServiceWorkerProvider;
class MODULES_EXPORT ServiceWorkerContainer final
@@ -84,9 +83,9 @@ class MODULES_EXPORT ServiceWorkerContainer final
void ContextDestroyed(ExecutionContext*) override;
// WebServiceWorkerProviderClient implementation.
- void SetController(std::unique_ptr<WebServiceWorker::Handle>,
+ void SetController(WebServiceWorkerObjectInfo,
bool should_notify_controller_change) override;
- void DispatchMessageEvent(std::unique_ptr<WebServiceWorker::Handle>,
+ void DispatchMessageEvent(WebServiceWorkerObjectInfo,
TransferableMessage) override;
void CountFeature(mojom::WebFeature) override;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.cc
index c1af3c5b759..3f37a5898fb 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.cc
@@ -6,11 +6,8 @@
#include <memory>
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
-#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
namespace blink {
@@ -19,30 +16,27 @@ ServiceWorkerContainerClient::ServiceWorkerContainerClient(
std::unique_ptr<WebServiceWorkerProvider> provider)
: Supplement<Document>(document), provider_(std::move(provider)) {}
-ServiceWorkerContainerClient::ServiceWorkerContainerClient(
- WorkerClients& clients,
- std::unique_ptr<WebServiceWorkerProvider> provider)
- : Supplement<WorkerClients>(clients), provider_(std::move(provider)) {}
-
ServiceWorkerContainerClient::~ServiceWorkerContainerClient() = default;
const char ServiceWorkerContainerClient::kSupplementName[] =
"ServiceWorkerContainerClient";
-ServiceWorkerContainerClient* ServiceWorkerContainerClient::From(
- ExecutionContext* context) {
- if (!context)
+ServiceWorker* ServiceWorkerContainerClient::GetOrCreateServiceWorker(
+ WebServiceWorkerObjectInfo info) {
+ if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId)
return nullptr;
- if (context->IsWorkerGlobalScope()) {
- WorkerClients* worker_clients = ToWorkerGlobalScope(context)->Clients();
- DCHECK(worker_clients);
- ServiceWorkerContainerClient* client =
- Supplement<WorkerClients>::From<ServiceWorkerContainerClient>(
- worker_clients);
- DCHECK(client);
- return client;
+ ServiceWorker* worker = service_worker_objects_.at(info.version_id);
+ if (!worker) {
+ worker = new ServiceWorker(GetSupplementable(), std::move(info));
+ service_worker_objects_.Set(info.version_id, worker);
}
- Document* document = ToDocument(context);
+ return worker;
+}
+
+ServiceWorkerContainerClient* ServiceWorkerContainerClient::From(
+ Document* document) {
+ if (!document)
+ return nullptr;
if (!document->GetFrame() || !document->GetFrame()->Client())
return nullptr;
@@ -57,11 +51,9 @@ ServiceWorkerContainerClient* ServiceWorkerContainerClient::From(
return client;
}
-void ProvideServiceWorkerContainerClientToWorker(
- WorkerClients* clients,
- std::unique_ptr<WebServiceWorkerProvider> provider) {
- clients->ProvideSupplement(
- new ServiceWorkerContainerClient(*clients, std::move(provider)));
+void ServiceWorkerContainerClient::Trace(blink::Visitor* visitor) {
+ visitor->Trace(service_worker_objects_);
+ Supplement<Document>::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.h
index 639bcb27662..91cdb99791d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_client.h
@@ -6,44 +6,44 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_CONTAINER_CLIENT_H_
#include <memory>
+
+#include "base/macros.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
-class ExecutionContext;
class WebServiceWorkerProvider;
// This mainly exists to provide access to WebServiceWorkerProvider.
-// Owned by Document (or WorkerClients).
+// Owned by Document.
class MODULES_EXPORT ServiceWorkerContainerClient final
: public GarbageCollectedFinalized<ServiceWorkerContainerClient>,
public Supplement<Document>,
- public Supplement<WorkerClients>,
public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerContainerClient);
- WTF_MAKE_NONCOPYABLE(ServiceWorkerContainerClient);
public:
static const char kSupplementName[];
ServiceWorkerContainerClient(Document&,
std::unique_ptr<WebServiceWorkerProvider>);
- ServiceWorkerContainerClient(WorkerClients&,
- std::unique_ptr<WebServiceWorkerProvider>);
virtual ~ServiceWorkerContainerClient();
+ // Returns the ServiceWorker object described by the object info in current
+ // execution context. Creates a new object if needed, or else returns the
+ // existing one.
+ ServiceWorker* GetOrCreateServiceWorker(WebServiceWorkerObjectInfo);
+
WebServiceWorkerProvider* Provider() { return provider_.get(); }
- static ServiceWorkerContainerClient* From(ExecutionContext*);
+ static ServiceWorkerContainerClient* From(Document*);
- void Trace(blink::Visitor* visitor) override {
- Supplement<Document>::Trace(visitor);
- Supplement<WorkerClients>::Trace(visitor);
- }
+ void Trace(blink::Visitor* visitor) override;
const char* NameInHeapSnapshot() const override {
return "ServiceWorkerContainerClient";
@@ -51,11 +51,16 @@ class MODULES_EXPORT ServiceWorkerContainerClient final
private:
std::unique_ptr<WebServiceWorkerProvider> provider_;
-};
+ // Map from service worker version id to JavaScript ServiceWorker object in
+ // current execution context.
+ HeapHashMap<int64_t,
+ WeakMember<ServiceWorker>,
+ WTF::IntHash<int64_t>,
+ WTF::UnsignedWithZeroKeyHashTraits<int64_t>>
+ service_worker_objects_;
-MODULES_EXPORT void ProvideServiceWorkerContainerClientToWorker(
- WorkerClients*,
- std::unique_ptr<WebServiceWorkerProvider>);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContainerClient);
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
index 6099c2337ba..a750ba02712 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
@@ -131,6 +131,7 @@ class NotReachedWebServiceWorkerProvider : public WebServiceWorkerProvider {
void RegisterServiceWorker(
const WebURL& pattern,
const WebURL& script_url,
+ blink::mojom::ScriptType script_type,
mojom::ServiceWorkerUpdateViaCache update_via_cache,
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks)
override {
@@ -251,6 +252,7 @@ class StubWebServiceWorkerProvider {
StubWebServiceWorkerProvider()
: register_call_count_(0),
get_registration_call_count_(0),
+ script_type_(mojom::ScriptType::kClassic),
update_via_cache_(mojom::ServiceWorkerUpdateViaCache::kImports) {}
// Creates a WebServiceWorkerProvider. This can outlive the
@@ -266,6 +268,7 @@ class StubWebServiceWorkerProvider {
const WebURL& RegisterScriptURL() { return register_script_url_; }
size_t GetRegistrationCallCount() { return get_registration_call_count_; }
const WebURL& GetRegistrationURL() { return get_registration_url_; }
+ mojom::ScriptType ScriptType() const { return script_type_; }
mojom::ServiceWorkerUpdateViaCache UpdateViaCache() const {
return update_via_cache_;
}
@@ -281,12 +284,14 @@ class StubWebServiceWorkerProvider {
void RegisterServiceWorker(
const WebURL& pattern,
const WebURL& script_url,
+ blink::mojom::ScriptType script_type,
mojom::ServiceWorkerUpdateViaCache update_via_cache,
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks)
override {
owner_.register_call_count_++;
owner_.register_scope_ = pattern;
owner_.register_script_url_ = script_url;
+ owner_.script_type_ = script_type;
owner_.update_via_cache_ = update_via_cache;
registration_callbacks_to_delete_.push_back(std::move(callbacks));
}
@@ -320,6 +325,7 @@ class StubWebServiceWorkerProvider {
WebURL register_script_url_;
size_t get_registration_call_count_;
WebURL get_registration_url_;
+ mojom::ScriptType script_type_;
mojom::ServiceWorkerUpdateViaCache update_via_cache_;
};
@@ -346,6 +352,7 @@ TEST_F(ServiceWorkerContainerTest,
stub_provider.RegisterScope());
EXPECT_EQ(WebURL(KURL("http://localhost/x/y/worker.js")),
stub_provider.RegisterScriptURL());
+ EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
stub_provider.UpdateViaCache());
}
@@ -367,6 +374,7 @@ TEST_F(ServiceWorkerContainerTest,
EXPECT_EQ(1ul, stub_provider.GetRegistrationCallCount());
EXPECT_EQ(WebURL(KURL("http://localhost/x/index.html")),
stub_provider.GetRegistrationURL());
+ EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
stub_provider.UpdateViaCache());
}
@@ -395,10 +403,39 @@ TEST_F(ServiceWorkerContainerTest,
stub_provider.RegisterScope());
EXPECT_EQ(WebURL(KURL(KURL(), "http://localhost/x/y/worker.js")),
stub_provider.RegisterScriptURL());
+ EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kNone,
stub_provider.UpdateViaCache());
}
}
+TEST_F(ServiceWorkerContainerTest, Register_TypeOptionDelegatesToProvider) {
+ SetPageURL("http://localhost/x/index.html");
+
+ StubWebServiceWorkerProvider stub_provider;
+ Provide(stub_provider.Provider());
+
+ ServiceWorkerContainer* container = ServiceWorkerContainer::Create(
+ GetExecutionContext(), GetNavigatorServiceWorker());
+
+ // register
+ {
+ ScriptState::Scope script_scope(GetScriptState());
+ RegistrationOptions options;
+ options.setType("module");
+ container->registerServiceWorker(GetScriptState(), "/x/y/worker.js",
+ options);
+
+ EXPECT_EQ(1ul, stub_provider.RegisterCallCount());
+ EXPECT_EQ(WebURL(KURL(KURL(), "http://localhost/x/y/")),
+ stub_provider.RegisterScope());
+ EXPECT_EQ(WebURL(KURL(KURL(), "http://localhost/x/y/worker.js")),
+ stub_provider.RegisterScriptURL());
+ EXPECT_EQ(mojom::ScriptType::kModule, stub_provider.ScriptType());
+ EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
+ stub_provider.UpdateViaCache());
+ }
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.cc
index 3502f8a7dc3..e958fc84a3b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.cc
@@ -127,6 +127,14 @@ DOMException* ServiceWorkerError::Take(ScriptPromiseResolver*,
}
// static
+DOMException* ServiceWorkerError::GetException(
+ ScriptPromiseResolver* resolver,
+ mojom::blink::ServiceWorkerErrorType error,
+ const String& error_msg) {
+ return Take(resolver, WebServiceWorkerError(error, error_msg));
+}
+
+// static
v8::Local<v8::Value> ServiceWorkerErrorForUpdate::Take(
ScriptPromiseResolver* resolver,
const WebServiceWorkerError& web_error) {
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h
index f6d34c61eb7..27f011d1985 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_ERROR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_ERROR_H_
+#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "v8/include/v8.h"
@@ -48,6 +49,12 @@ class ServiceWorkerError {
using WebType = const WebServiceWorkerError&;
static DOMException* Take(ScriptPromiseResolver*,
const WebServiceWorkerError& web_error);
+
+ // TODO(crbug.com/879019): Eventually we'll remove WebServiceWorkerError and
+ // use this GetException() everywhere instead of the above Take().
+ static DOMException* GetException(ScriptPromiseResolver*,
+ mojom::blink::ServiceWorkerErrorType error,
+ const String& error_msg);
};
class ServiceWorkerErrorForUpdate : public ServiceWorkerError {
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index 3bea7b455ec..1430d951115 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -40,11 +40,10 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
-#include "third_party/blink/renderer/core/frame/deprecation.h"
-#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/worker_inspector_controller.h"
#include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
@@ -53,6 +52,7 @@
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/installed_scripts_manager.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
+#include "third_party/blink/renderer/core/workers/worker_module_tree_client.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
@@ -74,6 +74,20 @@
namespace blink {
+namespace {
+
+void DidSkipWaiting(ScriptPromiseResolver* resolver, bool success) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed())
+ return;
+ // Per spec the promise returned by skipWaiting() can never reject.
+ if (!success)
+ return;
+ resolver->Resolve();
+}
+
+} // namespace
+
ServiceWorkerGlobalScope* ServiceWorkerGlobalScope::Create(
ServiceWorkerThread* thread,
std::unique_ptr<GlobalScopeCreationParams> creation_params,
@@ -114,6 +128,7 @@ void ServiceWorkerGlobalScope::ReadyToEvaluateScript() {
void ServiceWorkerGlobalScope::EvaluateClassicScript(
const KURL& script_url,
+ AccessControlStatus access_control_status,
String source_code,
std::unique_ptr<Vector<char>> cached_meta_data) {
DCHECK(IsContextThread());
@@ -121,8 +136,8 @@ void ServiceWorkerGlobalScope::EvaluateClassicScript(
if (!evaluate_script_ready_) {
evaluate_script_ =
WTF::Bind(&ServiceWorkerGlobalScope::EvaluateClassicScript,
- WrapWeakPersistent(this), script_url, std::move(source_code),
- std::move(cached_meta_data));
+ WrapWeakPersistent(this), script_url, access_control_status,
+ std::move(source_code), std::move(cached_meta_data));
return;
}
@@ -132,37 +147,37 @@ void ServiceWorkerGlobalScope::EvaluateClassicScript(
if (installed_scripts_manager &&
installed_scripts_manager->IsScriptInstalled(script_url)) {
// GetScriptData blocks until the script is received from the browser.
- InstalledScriptsManager::ScriptData script_data;
- InstalledScriptsManager::ScriptStatus status =
- installed_scripts_manager->GetScriptData(script_url, &script_data);
- if (status == InstalledScriptsManager::ScriptStatus::kFailed) {
+ std::unique_ptr<InstalledScriptsManager::ScriptData> script_data =
+ installed_scripts_manager->GetScriptData(script_url);
+ if (!script_data) {
close();
return;
}
DCHECK(source_code.IsEmpty());
DCHECK(!cached_meta_data);
- source_code = script_data.TakeSourceText();
- cached_meta_data = script_data.TakeMetaData();
+ source_code = script_data->TakeSourceText();
+ cached_meta_data = script_data->TakeMetaData();
base::Optional<ContentSecurityPolicyResponseHeaders>
content_security_policy_raw_headers =
- script_data.GetContentSecurityPolicyResponseHeaders();
+ script_data->GetContentSecurityPolicyResponseHeaders();
ApplyContentSecurityPolicyFromHeaders(
content_security_policy_raw_headers.value());
- String referrer_policy = script_data.GetReferrerPolicy();
+ String referrer_policy = script_data->GetReferrerPolicy();
if (!referrer_policy.IsNull())
ParseAndSetReferrerPolicy(referrer_policy);
std::unique_ptr<Vector<String>> origin_trial_tokens =
- script_data.CreateOriginTrialTokens();
+ script_data->CreateOriginTrialTokens();
OriginTrialContext::AddTokens(this, origin_trial_tokens.get());
ReportingProxy().DidLoadInstalledScript();
}
- WorkerGlobalScope::EvaluateClassicScript(script_url, source_code,
+ WorkerGlobalScope::EvaluateClassicScript(script_url, access_control_status,
+ source_code,
std::move(cached_meta_data));
}
@@ -170,13 +185,24 @@ void ServiceWorkerGlobalScope::ImportModuleScript(
const KURL& module_url_record,
FetchClientSettingsObjectSnapshot* outside_settings_object,
network::mojom::FetchCredentialsMode credentials_mode) {
- // TODO(nhiroki): Implement module loading for service workers.
- // (https://crbug.com/824647)
- NOTREACHED();
+ Modulator* modulator = Modulator::From(ScriptController()->GetScriptState());
+
+ FetchModuleScript(module_url_record, outside_settings_object,
+ mojom::RequestContextType::SERVICE_WORKER, credentials_mode,
+ ModuleScriptCustomFetchType::kWorkerConstructor,
+ new WorkerModuleTreeClient(modulator));
+}
+
+void ServiceWorkerGlobalScope::Dispose() {
+ DCHECK(IsContextThread());
+ ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
+ ->WillDestroyWorkerContext();
+ WorkerGlobalScope::Dispose();
}
void ServiceWorkerGlobalScope::CountWorkerScript(size_t script_size,
size_t cached_metadata_size) {
+ DCHECK_EQ(GetScriptType(), ScriptType::kClassic);
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, script_size_histogram,
("ServiceWorker.ScriptSize", 1000, 5000000, 50));
@@ -189,23 +215,29 @@ void ServiceWorkerGlobalScope::CountWorkerScript(size_t script_size,
script_cached_metadata_size_histogram.Count(cached_metadata_size);
}
- RecordScriptSize(script_size, cached_metadata_size);
+ CountScriptInternal(script_size, cached_metadata_size);
}
void ServiceWorkerGlobalScope::CountImportedScript(
size_t script_size,
size_t cached_metadata_size) {
- RecordScriptSize(script_size, cached_metadata_size);
+ DCHECK_EQ(GetScriptType(), ScriptType::kClassic);
+ CountScriptInternal(script_size, cached_metadata_size);
}
-void ServiceWorkerGlobalScope::RecordScriptSize(size_t script_size,
- size_t cached_metadata_size) {
- ++script_count_;
- script_total_size_ += script_size;
- script_cached_metadata_total_size_ += cached_metadata_size;
-}
+void ServiceWorkerGlobalScope::DidEvaluateScript() {
+ DCHECK(!did_evaluate_script_);
+ did_evaluate_script_ = true;
-void ServiceWorkerGlobalScope::DidEvaluateClassicScript() {
+ // Skip recording UMAs for module scripts because there're no ways to get the
+ // number of static-imported scripts and the total size of the imported
+ // scripts.
+ if (GetScriptType() == ScriptType::kModule) {
+ return;
+ }
+
+ // TODO(asamidoi,nhiroki): Record the UMAs for module scripts, or remove them
+ // if they're no longer used.
DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, script_count_histogram,
("ServiceWorker.ScriptCount", 1, 1000, 50));
script_count_histogram.Count(script_count_);
@@ -219,14 +251,14 @@ void ServiceWorkerGlobalScope::DidEvaluateClassicScript() {
("ServiceWorker.ScriptCachedMetadataTotalSize", 1000, 50000000, 50));
cached_metadata_histogram.Count(script_cached_metadata_total_size_);
}
- did_evaluate_script_ = true;
}
-ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
- const RequestInfo& input,
- const RequestInit& init,
- ExceptionState& exception_state) {
- return GlobalFetch::fetch(script_state, *this, input, init, exception_state);
+void ServiceWorkerGlobalScope::CountScriptInternal(
+ size_t script_size,
+ size_t cached_metadata_size) {
+ ++script_count_;
+ script_total_size_ += script_size;
+ script_cached_metadata_total_size_ += cached_metadata_size;
}
ServiceWorkerClients* ServiceWorkerGlobalScope::clients() {
@@ -247,12 +279,15 @@ ScriptPromise ServiceWorkerGlobalScope::skipWaiting(ScriptState* script_state) {
return ScriptPromise();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
ServiceWorkerGlobalScopeClient::From(execution_context)
- ->SkipWaiting(
- std::make_unique<CallbackPromiseAdapter<void, void>>(resolver));
- return promise;
+ ->SkipWaiting(WTF::Bind(&DidSkipWaiting, WrapPersistent(resolver)));
+ return resolver->Promise();
+}
+
+void ServiceWorkerGlobalScope::BindServiceWorkerHost(
+ mojom::blink::ServiceWorkerHostAssociatedPtrInfo service_worker_host) {
+ ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
+ ->BindServiceWorkerHost(std::move(service_worker_host));
}
void ServiceWorkerGlobalScope::SetRegistration(
@@ -263,6 +298,18 @@ void ServiceWorkerGlobalScope::SetRegistration(
GetExecutionContext(), base::WrapUnique(handle.release()));
}
+ServiceWorker* ServiceWorkerGlobalScope::GetOrCreateServiceWorker(
+ WebServiceWorkerObjectInfo info) {
+ if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId)
+ return nullptr;
+ ServiceWorker* worker = service_worker_objects_.at(info.version_id);
+ if (!worker) {
+ worker = new ServiceWorker(this, std::move(info));
+ service_worker_objects_.Set(info.version_id, worker);
+ }
+ return worker;
+}
+
bool ServiceWorkerGlobalScope::AddEventListenerInternal(
const AtomicString& event_type,
EventListener* listener,
@@ -310,6 +357,7 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith(
void ServiceWorkerGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(clients_);
visitor->Trace(registration_);
+ visitor->Trace(service_worker_objects_);
WorkerGlobalScope::Trace(visitor);
}
@@ -319,22 +367,21 @@ void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls,
GetThread()->GetInstalledScriptsManager();
for (auto& url : urls) {
KURL completed_url = CompleteURL(url);
- // Counts the usage of importScripts() of new scripts after installation
- // because we want to deprecate such usage (https://crbug.com/719052).
- // This will undercount because installed scripts manager is only provided
- // to installed service workers on startup, but this gives us an idea of
- // the usage.
- if (installed_scripts_manager &&
- !installed_scripts_manager->IsScriptInstalled(completed_url)) {
- DCHECK(installed_scripts_manager->IsScriptInstalled(Url()));
- CountFeature(WebFeature::kServiceWorkerImportScriptNotInstalled);
- Deprecation::CountDeprecation(
- this, WebFeature::kServiceWorkerImportScriptNotInstalled);
- }
// Bust the MemoryCache to ensure script requests reach the browser-side
// and get added to and retrieved from the ServiceWorker's script cache.
// FIXME: Revisit in light of the solution to crbug/388375.
RemoveURLFromMemoryCache(completed_url);
+
+ if (installed_scripts_manager &&
+ !installed_scripts_manager->IsScriptInstalled(completed_url)) {
+ DCHECK(installed_scripts_manager->IsScriptInstalled(Url()));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ "Failed to import '" + completed_url.ElidedString() +
+ "'. importScripts() of new scripts after service worker "
+ "installation is not allowed.");
+ return;
+ }
}
WorkerGlobalScope::importScripts(urls, exception_state);
}
@@ -347,6 +394,13 @@ ServiceWorkerGlobalScope::CreateWorkerScriptCachedMetadataHandler(
meta_data);
}
+ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
+ const RequestInfo& input,
+ const RequestInit& init,
+ ExceptionState& exception_state) {
+ return GlobalFetch::fetch(script_state, *this, input, init, exception_state);
+}
+
void ServiceWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
WorkerGlobalScope::ExceptionThrown(event);
if (WorkerThreadDebugger* debugger =
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index f00b65661e5..4fc509a1165 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -31,11 +31,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_GLOBAL_SCOPE_H_
#include <memory>
+#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -70,12 +72,14 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
// Implements WorkerGlobalScope.
void EvaluateClassicScript(
const KURL& script_url,
+ AccessControlStatus access_control_status,
String source_code,
std::unique_ptr<Vector<char>> cached_meta_data) override;
void ImportModuleScript(
const KURL& module_url_record,
FetchClientSettingsObjectSnapshot* outside_settings_object,
network::mojom::FetchCredentialsMode) override;
+ void Dispose() override;
// Counts an evaluated script and its size. Called for the main worker script.
void CountWorkerScript(size_t script_size, size_t cached_metadata_size);
@@ -85,7 +89,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
void CountImportedScript(size_t script_size, size_t cached_metadata_size);
// Called when the main worker script is evaluated.
- void DidEvaluateClassicScript();
+ void DidEvaluateScript();
// ServiceWorkerGlobalScope.idl
ServiceWorkerClients* clients();
@@ -98,8 +102,15 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
ScriptPromise skipWaiting(ScriptState*);
+ void BindServiceWorkerHost(mojom::blink::ServiceWorkerHostAssociatedPtrInfo);
+
void SetRegistration(std::unique_ptr<WebServiceWorkerRegistration::Handle>);
+ // Returns the ServiceWorker object described by the object info in current
+ // execution context. Creates a new object if needed, or else returns the
+ // existing one.
+ ServiceWorker* GetOrCreateServiceWorker(WebServiceWorkerObjectInfo);
+
// EventTarget
const AtomicString& InterfaceName() const override;
@@ -146,12 +157,19 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
const Vector<char>* meta_data) override;
void ExceptionThrown(ErrorEvent*) override;
- // Records the |script_size| and |cached_metadata_size| for UMA to measure the
+ // Counts the |script_size| and |cached_metadata_size| for UMA to measure the
// number of scripts and the total bytes of scripts.
- void RecordScriptSize(size_t script_size, size_t cached_metadata_size);
+ void CountScriptInternal(size_t script_size, size_t cached_metadata_size);
Member<ServiceWorkerClients> clients_;
Member<ServiceWorkerRegistration> registration_;
+ // Map from service worker version id to JavaScript ServiceWorker object in
+ // current execution context.
+ HeapHashMap<int64_t,
+ WeakMember<ServiceWorker>,
+ WTF::IntHash<int64_t>,
+ WTF::UnsignedWithZeroKeyHashTraits<int64_t>>
+ service_worker_objects_;
bool did_evaluate_script_ = false;
size_t script_count_ = 0;
size_t script_total_size_ = 0;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
index ae17974d99b..5810258d03b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
@@ -33,64 +33,130 @@
#include <memory>
#include <utility>
#include "third_party/blink/public/platform/modules/payments/web_payment_handler_response.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_response.h"
-#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+namespace {
+
+void DidNavigateOrOpenWindow(ScriptPromiseResolver* resolver,
+ bool success,
+ mojom::blink::ServiceWorkerClientInfoPtr info,
+ const String& error_msg) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
+ }
+
+ if (!success) {
+ DCHECK(!info);
+ DCHECK(!error_msg.IsNull());
+ ScriptState::Scope scope(resolver->GetScriptState());
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ resolver->GetScriptState()->GetIsolate(), error_msg));
+ return;
+ }
+ ServiceWorkerWindowClient* window_client = nullptr;
+ // Even if the open/navigation succeeded, |info| may be null if information of
+ // the opened/navigated window could not be obtained (this can happen for a
+ // cross-origin window, or if the browser process could not get the
+ // information in time before the window was closed).
+ if (info)
+ window_client = ServiceWorkerWindowClient::Create(*info);
+ resolver->Resolve(window_client);
+}
+
+} // namespace
+
ServiceWorkerGlobalScopeClient::ServiceWorkerGlobalScopeClient(
WebServiceWorkerContextClient& client)
: client_(client) {}
-void ServiceWorkerGlobalScopeClient::GetClient(
- const WebString& id,
- std::unique_ptr<WebServiceWorkerClientCallbacks> callbacks) {
- client_.GetClient(id, std::move(callbacks));
+void ServiceWorkerGlobalScopeClient::GetClient(const String& id,
+ GetClientCallback callback) {
+ service_worker_host_->GetClient(id, std::move(callback));
}
void ServiceWorkerGlobalScopeClient::GetClients(
- const WebServiceWorkerClientQueryOptions& options,
- std::unique_ptr<WebServiceWorkerClientsCallbacks> callbacks) {
- client_.GetClients(options, std::move(callbacks));
+ mojom::blink::ServiceWorkerClientQueryOptionsPtr options,
+ GetClientsCallback callback) {
+ service_worker_host_->GetClients(std::move(options), std::move(callback));
}
void ServiceWorkerGlobalScopeClient::OpenWindowForClients(
- const WebURL& url,
- std::unique_ptr<WebServiceWorkerClientCallbacks> callbacks) {
- client_.OpenNewTab(url, std::move(callbacks));
+ const KURL& url,
+ ScriptPromiseResolver* resolver) {
+ service_worker_host_->OpenNewTab(
+ url, WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
void ServiceWorkerGlobalScopeClient::OpenWindowForPaymentHandler(
- const WebURL& url,
- std::unique_ptr<WebServiceWorkerClientCallbacks> callbacks) {
- client_.OpenPaymentHandlerWindow(url, std::move(callbacks));
+ const KURL& url,
+ ScriptPromiseResolver* resolver) {
+ service_worker_host_->OpenPaymentHandlerWindow(
+ url, WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
-void ServiceWorkerGlobalScopeClient::SetCachedMetadata(const WebURL& url,
+void ServiceWorkerGlobalScopeClient::SetCachedMetadata(const KURL& url,
const char* data,
size_t size) {
- client_.SetCachedMetadata(url, data, size);
+ Vector<uint8_t> meta_data;
+ meta_data.Append(data, size);
+ service_worker_host_->SetCachedMetadata(url, meta_data);
+}
+
+void ServiceWorkerGlobalScopeClient::ClearCachedMetadata(const KURL& url) {
+ service_worker_host_->ClearCachedMetadata(url);
+}
+
+void ServiceWorkerGlobalScopeClient::PostMessageToClient(
+ const String& client_uuid,
+ BlinkTransferableMessage message) {
+ service_worker_host_->PostMessageToClient(client_uuid, std::move(message));
+}
+
+void ServiceWorkerGlobalScopeClient::SkipWaiting(SkipWaitingCallback callback) {
+ service_worker_host_->SkipWaiting(std::move(callback));
+}
+
+void ServiceWorkerGlobalScopeClient::Claim(ClaimCallback callback) {
+ service_worker_host_->ClaimClients(std::move(callback));
}
-void ServiceWorkerGlobalScopeClient::ClearCachedMetadata(const WebURL& url) {
- client_.ClearCachedMetadata(url);
+void ServiceWorkerGlobalScopeClient::Focus(const String& client_uuid,
+ FocusCallback callback) {
+ service_worker_host_->FocusClient(client_uuid, std::move(callback));
+}
+
+void ServiceWorkerGlobalScopeClient::Navigate(const String& client_uuid,
+ const KURL& url,
+ ScriptPromiseResolver* resolver) {
+ service_worker_host_->NavigateClient(
+ client_uuid, url,
+ WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
void ServiceWorkerGlobalScopeClient::DidHandleActivateEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleActivateEvent(event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchAbortEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleBackgroundFetchAbortEvent(event_id, status,
event_dispatch_time);
}
@@ -98,7 +164,7 @@ void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchAbortEvent(
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchClickEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleBackgroundFetchClickEvent(event_id, status,
event_dispatch_time);
}
@@ -106,7 +172,7 @@ void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchClickEvent(
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchFailEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleBackgroundFetchFailEvent(event_id, status,
event_dispatch_time);
}
@@ -114,7 +180,7 @@ void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchFailEvent(
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchSuccessEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleBackgroundFetchSuccessEvent(event_id, status,
event_dispatch_time);
}
@@ -122,45 +188,50 @@ void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchSuccessEvent(
void ServiceWorkerGlobalScopeClient::DidHandleCookieChangeEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleCookieChangeEvent(event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleExtendableMessageEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleExtendableMessageEvent(event_id, status,
event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEventWithNoResponse(
int fetch_event_id,
- double event_dispatch_time) {
- client_.RespondToFetchEventWithNoResponse(fetch_event_id,
- event_dispatch_time);
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
+ client_.RespondToFetchEventWithNoResponse(fetch_event_id, event_dispatch_time,
+ respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEvent(
int fetch_event_id,
const WebServiceWorkerResponse& response,
- double event_dispatch_time) {
- client_.RespondToFetchEvent(fetch_event_id, response, event_dispatch_time);
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
+ client_.RespondToFetchEvent(fetch_event_id, response, event_dispatch_time,
+ respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEventWithResponseStream(
int fetch_event_id,
const WebServiceWorkerResponse& response,
WebServiceWorkerStreamHandle* stream_handle,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
client_.RespondToFetchEventWithResponseStream(
- fetch_event_id, response, stream_handle, event_dispatch_time);
+ fetch_event_id, response, stream_handle, event_dispatch_time,
+ respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToAbortPaymentEvent(
int event_id,
bool abort_payment,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.RespondToAbortPaymentEvent(event_id, abort_payment,
event_dispatch_time);
}
@@ -168,35 +239,35 @@ void ServiceWorkerGlobalScopeClient::RespondToAbortPaymentEvent(
void ServiceWorkerGlobalScopeClient::RespondToCanMakePaymentEvent(
int event_id,
bool response,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.RespondToCanMakePaymentEvent(event_id, response, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::RespondToPaymentRequestEvent(
int event_id,
const WebPaymentHandlerResponse& response,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.RespondToPaymentRequestEvent(event_id, response, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleFetchEvent(
int fetch_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleFetchEvent(fetch_event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleInstallEvent(
int install_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleInstallEvent(install_event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleNotificationClickEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleNotificationClickEvent(event_id, status,
event_dispatch_time);
}
@@ -204,7 +275,7 @@ void ServiceWorkerGlobalScopeClient::DidHandleNotificationClickEvent(
void ServiceWorkerGlobalScopeClient::DidHandleNotificationCloseEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleNotificationCloseEvent(event_id, status,
event_dispatch_time);
}
@@ -212,21 +283,21 @@ void ServiceWorkerGlobalScopeClient::DidHandleNotificationCloseEvent(
void ServiceWorkerGlobalScopeClient::DidHandlePushEvent(
int push_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandlePushEvent(push_event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleSyncEvent(
int sync_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleSyncEvent(sync_event_id, status, event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleAbortPaymentEvent(
int abort_payment_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleAbortPaymentEvent(abort_payment_event_id, status,
event_dispatch_time);
}
@@ -234,7 +305,7 @@ void ServiceWorkerGlobalScopeClient::DidHandleAbortPaymentEvent(
void ServiceWorkerGlobalScopeClient::DidHandleCanMakePaymentEvent(
int payment_request_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandleCanMakePaymentEvent(payment_request_event_id, status,
event_dispatch_time);
}
@@ -242,38 +313,20 @@ void ServiceWorkerGlobalScopeClient::DidHandleCanMakePaymentEvent(
void ServiceWorkerGlobalScopeClient::DidHandlePaymentRequestEvent(
int payment_request_event_id,
mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
client_.DidHandlePaymentRequestEvent(payment_request_event_id, status,
event_dispatch_time);
}
-void ServiceWorkerGlobalScopeClient::PostMessageToClient(
- const WebString& client_uuid,
- TransferableMessage message) {
- client_.PostMessageToClient(client_uuid, std::move(message));
-}
-
-void ServiceWorkerGlobalScopeClient::SkipWaiting(
- std::unique_ptr<WebServiceWorkerSkipWaitingCallbacks> callbacks) {
- client_.SkipWaiting(std::move(callbacks));
-}
-
-void ServiceWorkerGlobalScopeClient::Claim(
- std::unique_ptr<WebServiceWorkerClientsClaimCallbacks> callbacks) {
- client_.Claim(std::move(callbacks));
-}
-
-void ServiceWorkerGlobalScopeClient::Focus(
- const WebString& client_uuid,
- std::unique_ptr<WebServiceWorkerClientCallbacks> callback) {
- client_.Focus(client_uuid, std::move(callback));
+void ServiceWorkerGlobalScopeClient::BindServiceWorkerHost(
+ mojom::blink::ServiceWorkerHostAssociatedPtrInfo service_worker_host) {
+ DCHECK(service_worker_host.is_valid());
+ DCHECK(!service_worker_host_);
+ service_worker_host_.Bind(std::move(service_worker_host));
}
-void ServiceWorkerGlobalScopeClient::Navigate(
- const WebString& client_uuid,
- const WebURL& url,
- std::unique_ptr<WebServiceWorkerClientCallbacks> callback) {
- client_.Navigate(client_uuid, url, std::move(callback));
+void ServiceWorkerGlobalScopeClient::WillDestroyWorkerContext() {
+ service_worker_host_.reset();
}
const char ServiceWorkerGlobalScopeClient::kSupplementName[] =
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
index 91096359d82..a5336ece430 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
@@ -32,128 +32,138 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_GLOBAL_SCOPE_CLIENT_H_
#include <memory>
-#include "third_party/blink/public/common/message_port/transferable_message.h"
+
+#include "base/macros.h"
+#include "third_party/blink/public/common/messaging/transferable_message.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_claim_callbacks.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_skip_waiting_callbacks.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_stream_handle.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
struct WebPaymentHandlerResponse;
-struct WebServiceWorkerClientQueryOptions;
class ExecutionContext;
+class KURL;
+class ScriptPromiseResolver;
class WebServiceWorkerContextClient;
class WebServiceWorkerResponse;
-class WebURL;
class WorkerClients;
// See WebServiceWorkerContextClient for documentation for the methods in this
// class.
-class MODULES_EXPORT ServiceWorkerGlobalScopeClient
- : public GarbageCollected<ServiceWorkerGlobalScopeClient>,
+class MODULES_EXPORT ServiceWorkerGlobalScopeClient final
+ : public GarbageCollectedFinalized<ServiceWorkerGlobalScopeClient>,
public Supplement<WorkerClients> {
USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerGlobalScopeClient);
- WTF_MAKE_NONCOPYABLE(ServiceWorkerGlobalScopeClient);
public:
+ using ClaimCallback = mojom::blink::ServiceWorkerHost::ClaimClientsCallback;
+ using SkipWaitingCallback =
+ mojom::blink::ServiceWorkerHost::SkipWaitingCallback;
+ using GetClientCallback = mojom::blink::ServiceWorkerHost::GetClientCallback;
+ using GetClientsCallback =
+ mojom::blink::ServiceWorkerHost::GetClientsCallback;
+ using FocusCallback = mojom::blink::ServiceWorkerHost::FocusClientCallback;
+
static const char kSupplementName[];
explicit ServiceWorkerGlobalScopeClient(WebServiceWorkerContextClient&);
// Called from ServiceWorkerClients.
- void GetClient(const WebString&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>);
- void GetClients(const WebServiceWorkerClientQueryOptions&,
- std::unique_ptr<WebServiceWorkerClientsCallbacks>);
- void OpenWindowForClients(const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>);
- void OpenWindowForPaymentHandler(
- const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>);
- void SetCachedMetadata(const WebURL&, const char*, size_t);
- void ClearCachedMetadata(const WebURL&);
+ void GetClient(const String&, GetClientCallback);
+ void GetClients(mojom::blink::ServiceWorkerClientQueryOptionsPtr,
+ GetClientsCallback);
+ void OpenWindowForClients(const KURL&, ScriptPromiseResolver*);
+ void OpenWindowForPaymentHandler(const KURL&, ScriptPromiseResolver*);
+ void SetCachedMetadata(const KURL&, const char*, size_t);
+ void ClearCachedMetadata(const KURL&);
+ void PostMessageToClient(const String& client_uuid, BlinkTransferableMessage);
+ void SkipWaiting(SkipWaitingCallback);
+ void Claim(ClaimCallback);
+ void Focus(const String& client_uuid, FocusCallback);
+ void Navigate(const String& client_uuid, const KURL&, ScriptPromiseResolver*);
void DidHandleActivateEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleBackgroundFetchAbortEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleBackgroundFetchClickEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleBackgroundFetchFailEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
- void DidHandleBackgroundFetchSuccessEvent(int event_id,
- mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
+ void DidHandleBackgroundFetchSuccessEvent(
+ int event_id,
+ mojom::ServiceWorkerEventStatus,
+ base::TimeTicks event_dispatch_time);
void DidHandleCookieChangeEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleExtendableMessageEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
- void RespondToFetchEventWithNoResponse(int fetch_event_id,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
+ void RespondToFetchEventWithNoResponse(
+ int fetch_event_id,
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time);
void RespondToFetchEvent(int fetch_event_id,
const WebServiceWorkerResponse&,
- double event_dispatch_time);
- void RespondToFetchEventWithResponseStream(int fetch_event_id,
- const WebServiceWorkerResponse&,
- WebServiceWorkerStreamHandle*,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time);
+ void RespondToFetchEventWithResponseStream(
+ int fetch_event_id,
+ const WebServiceWorkerResponse&,
+ WebServiceWorkerStreamHandle*,
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time);
void RespondToAbortPaymentEvent(int event_id,
bool abort_payment,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void RespondToCanMakePaymentEvent(int event_id,
bool can_make_payment,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void RespondToPaymentRequestEvent(int event_id,
const WebPaymentHandlerResponse&,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleFetchEvent(int fetch_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleInstallEvent(int install_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleNotificationClickEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleNotificationCloseEvent(int event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandlePushEvent(int push_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleSyncEvent(int sync_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleAbortPaymentEvent(int abort_payment_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandleCanMakePaymentEvent(int payment_request_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ base::TimeTicks event_dispatch_time);
void DidHandlePaymentRequestEvent(int payment_request_event_id,
mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
- void PostMessageToClient(const WebString& client_uuid, TransferableMessage);
- void SkipWaiting(std::unique_ptr<WebServiceWorkerSkipWaitingCallbacks>);
- void Claim(std::unique_ptr<WebServiceWorkerClientsClaimCallbacks>);
- void Focus(const WebString& client_uuid,
- std::unique_ptr<WebServiceWorkerClientCallbacks>);
- void Navigate(const WebString& client_uuid,
- const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>);
+ base::TimeTicks event_dispatch_time);
+
+ void BindServiceWorkerHost(
+ mojom::blink::ServiceWorkerHostAssociatedPtrInfo service_worker_host);
+
+ void WillDestroyWorkerContext();
static ServiceWorkerGlobalScopeClient* From(ExecutionContext*);
@@ -161,6 +171,14 @@ class MODULES_EXPORT ServiceWorkerGlobalScopeClient
private:
WebServiceWorkerContextClient& client_;
+
+ // Lives on the service worker thread, is bound by BindServiceWorkerHost()
+ // which is triggered by the first Mojo call received on the service worker
+ // thread content::mojom::ServiceWorker::InitializeGlobalScope(), and is
+ // closed by WillDestroyWorkerContext().
+ mojom::blink::ServiceWorkerHostAssociatedPtr service_worker_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerGlobalScopeClient);
};
MODULES_EXPORT void ProvideServiceWorkerGlobalScopeClientToWorker(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
index f55fc9ae2e1..f5dd6631a21 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -34,9 +34,9 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
@@ -182,8 +182,13 @@ void ServiceWorkerGlobalScopeProxy::Trace(blink::Visitor* visitor) {
visitor->Trace(parent_execution_context_task_runners_);
}
-void ServiceWorkerGlobalScopeProxy::ReadyToEvaluateScript() {
- WorkerGlobalScope()->ReadyToEvaluateScript();
+void ServiceWorkerGlobalScopeProxy::BindServiceWorkerHost(
+ mojo::ScopedInterfaceEndpointHandle service_worker_host) {
+ DCHECK(WorkerGlobalScope()->IsContextThread());
+ WorkerGlobalScope()->BindServiceWorkerHost(
+ mojom::blink::ServiceWorkerHostAssociatedPtrInfo(
+ std::move(service_worker_host),
+ mojom::blink::ServiceWorkerHost::Version_));
}
void ServiceWorkerGlobalScopeProxy::SetRegistration(
@@ -192,6 +197,10 @@ void ServiceWorkerGlobalScopeProxy::SetRegistration(
WorkerGlobalScope()->SetRegistration(std::move(handle));
}
+void ServiceWorkerGlobalScopeProxy::ReadyToEvaluateScript() {
+ WorkerGlobalScope()->ReadyToEvaluateScript();
+}
+
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
int event_id,
const WebBackgroundFetchRegistration& registration) {
@@ -348,7 +357,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchExtendableMessageEvent(
int event_id,
TransferableMessage message,
const WebSecurityOrigin& source_origin,
- std::unique_ptr<WebServiceWorker::Handle> handle) {
+ WebServiceWorkerObjectInfo info) {
DCHECK(WorkerGlobalScope()->IsContextThread());
auto msg = ToBlinkTransferableMessage(std::move(message));
MessagePortArray* ports =
@@ -356,9 +365,8 @@ void ServiceWorkerGlobalScopeProxy::DispatchExtendableMessageEvent(
String origin;
if (!source_origin.IsOpaque())
origin = source_origin.ToString();
- ServiceWorker* source =
- ServiceWorker::From(worker_global_scope_->GetExecutionContext(),
- base::WrapUnique(handle.release()));
+ ServiceWorker* source = ServiceWorker::From(
+ worker_global_scope_->GetExecutionContext(), std::move(info));
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kMessage, event_id);
@@ -409,7 +417,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchFetchEvent(
void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<WebURLResponse> response,
- std::unique_ptr<WebDataConsumerHandle> data_consume_handle) {
+ mojo::ScopedDataPipeConsumerHandle data_pipe) {
DCHECK(WorkerGlobalScope()->IsContextThread());
auto it = pending_preload_fetch_events_.find(fetch_event_id);
DCHECK(it != pending_preload_fetch_events_.end());
@@ -417,7 +425,7 @@ void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadResponse(
DCHECK(fetch_event);
fetch_event->OnNavigationPreloadResponse(
WorkerGlobalScope()->ScriptController()->GetScriptState(),
- std::move(response), std::move(data_consume_handle));
+ std::move(response), std::move(data_pipe));
}
void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadError(
@@ -426,11 +434,15 @@ void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadError(
DCHECK(WorkerGlobalScope()->IsContextThread());
FetchEvent* fetch_event = pending_preload_fetch_events_.Take(fetch_event_id);
DCHECK(fetch_event);
- // Display an unsanitized console message.
- if (!error->unsanitized_message.IsEmpty()) {
+ // Display an error message to the console, preferring the unsanitized one if
+ // available.
+ const WebString& error_message = error->unsanitized_message.IsEmpty()
+ ? error->message
+ : error->unsanitized_message;
+ if (!error_message.IsEmpty()) {
WorkerGlobalScope()->AddConsoleMessage(ConsoleMessage::Create(
kWorkerMessageSource, blink::MessageLevel::kErrorMessageLevel,
- error->unsanitized_message));
+ error_message));
}
// Reject the preloadResponse promise.
fetch_event->OnNavigationPreloadError(
@@ -650,8 +662,11 @@ void ServiceWorkerGlobalScopeProxy::WillEvaluateClassicScript(
size_t script_size,
size_t cached_metadata_size) {
DCHECK(WorkerGlobalScope()->IsContextThread());
+ // TODO(asamidoi): Remove CountWorkerScript which is called for recording
+ // metrics if the metrics are no longer referenced, and then merge
+ // WillEvaluateClassicScript and WillEvaluateModuleScript for cleanup.
worker_global_scope_->CountWorkerScript(script_size, cached_metadata_size);
- Client().WillEvaluateClassicScript();
+ Client().WillEvaluateScript();
}
void ServiceWorkerGlobalScopeProxy::WillEvaluateImportedClassicScript(
@@ -661,10 +676,21 @@ void ServiceWorkerGlobalScopeProxy::WillEvaluateImportedClassicScript(
worker_global_scope_->CountImportedScript(script_size, cached_metadata_size);
}
+void ServiceWorkerGlobalScopeProxy::WillEvaluateModuleScript() {
+ DCHECK(WorkerGlobalScope()->IsContextThread());
+ Client().WillEvaluateScript();
+}
+
void ServiceWorkerGlobalScopeProxy::DidEvaluateClassicScript(bool success) {
DCHECK(WorkerGlobalScope()->IsContextThread());
- WorkerGlobalScope()->DidEvaluateClassicScript();
- Client().DidEvaluateClassicScript(success);
+ WorkerGlobalScope()->DidEvaluateScript();
+ Client().DidEvaluateScript(success);
+}
+
+void ServiceWorkerGlobalScopeProxy::DidEvaluateModuleScript(bool success) {
+ DCHECK(WorkerGlobalScope()->IsContextThread());
+ WorkerGlobalScope()->DidEvaluateScript();
+ Client().DidEvaluateScript(success);
}
void ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() {
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
index aad7210a856..374e56e66e7 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -38,7 +38,7 @@
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -48,7 +48,6 @@ namespace blink {
class FetchEvent;
class ParentExecutionContextTaskRunners;
class ServiceWorkerGlobalScope;
-class WebDataConsumerHandle;
class WebEmbeddedWorkerImpl;
class WebServiceWorkerContextClient;
struct WebServiceWorkerError;
@@ -77,9 +76,13 @@ class ServiceWorkerGlobalScopeProxy final
~ServiceWorkerGlobalScopeProxy() override;
// WebServiceWorkerContextProxy overrides:
- void ReadyToEvaluateScript() override;
+ void BindServiceWorkerHost(
+ mojo::ScopedInterfaceEndpointHandle service_worker_host) override;
void SetRegistration(
std::unique_ptr<WebServiceWorkerRegistration::Handle>) override;
+ // Must be called after the above BindServiceWorkerHost() and
+ // SetRegistration() got called.
+ void ReadyToEvaluateScript() override;
void DispatchActivateEvent(int) override;
void DispatchBackgroundFetchAbortEvent(
int event_id,
@@ -102,11 +105,10 @@ class ServiceWorkerGlobalScopeProxy final
TransferableMessage,
const WebSecurityOrigin& source_origin,
const WebServiceWorkerClientInfo&) override;
- void DispatchExtendableMessageEvent(
- int event_id,
- TransferableMessage,
- const WebSecurityOrigin& source_origin,
- std::unique_ptr<WebServiceWorker::Handle>) override;
+ void DispatchExtendableMessageEvent(int event_id,
+ TransferableMessage,
+ const WebSecurityOrigin& source_origin,
+ WebServiceWorkerObjectInfo) override;
void DispatchFetchEvent(int fetch_event_id,
const WebServiceWorkerRequest&,
bool navigation_preload_sent) override;
@@ -130,7 +132,7 @@ class ServiceWorkerGlobalScopeProxy final
void OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<WebURLResponse>,
- std::unique_ptr<WebDataConsumerHandle>) override;
+ mojo::ScopedDataPipeConsumerHandle data_pipe) override;
void OnNavigationPreloadError(
int fetch_event_id,
std::unique_ptr<WebServiceWorkerError>) override;
@@ -158,7 +160,9 @@ class ServiceWorkerGlobalScopeProxy final
size_t cached_metadata_size) override;
void WillEvaluateImportedClassicScript(size_t script_size,
size_t cached_metadata_size) override;
+ void WillEvaluateModuleScript() override;
void DidEvaluateClassicScript(bool success) override;
+ void DidEvaluateModuleScript(bool success) override;
void DidCloseWorkerGlobalScope() override;
void WillDestroyWorkerGlobalScope() override;
void DidTerminateWorkerThread() override;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
index 8138d1b4290..b42870a6348 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
@@ -7,36 +7,269 @@
#include <memory>
#include <utility>
+#include "base/barrier_closure.h"
+#include "base/threading/thread_checker.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_thread.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+using RawScriptData = ThreadSafeScriptContainer::RawScriptData;
+
+namespace {
+
+// Receiver is a class to read a Mojo data pipe. Received data are stored in
+// chunks. Lives on the IO thread. Receiver is owned by Internal via
+// BundledReceivers. It is created to read the script body or metadata from a
+// data pipe, and is destroyed when the read finishes.
+class Receiver {
+ public:
+ using BytesChunk = Vector<char>;
+
+ Receiver(mojo::ScopedDataPipeConsumerHandle handle,
+ uint64_t total_bytes,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : handle_(std::move(handle)),
+ watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ std::move(task_runner)),
+ remaining_bytes_(total_bytes) {}
+
+ void Start(base::OnceClosure callback) {
+ if (!handle_.is_valid()) {
+ std::move(callback).Run();
+ return;
+ }
+ callback_ = std::move(callback);
+ // Unretained is safe because |watcher_| is owned by |this|.
+ MojoResult rv = watcher_.Watch(
+ handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
+ WTF::BindRepeating(&Receiver::OnReadable, WTF::Unretained(this)));
+ DCHECK_EQ(MOJO_RESULT_OK, rv);
+ watcher_.ArmOrNotify();
+ }
+
+ void OnReadable(MojoResult) {
+ // It isn't necessary to handle MojoResult here since BeginReadDataRaw()
+ // returns an equivalent error.
+ const void* buffer = nullptr;
+ uint32_t bytes_read = 0;
+ MojoResult rv =
+ handle_->BeginReadData(&buffer, &bytes_read, MOJO_READ_DATA_FLAG_NONE);
+ switch (rv) {
+ case MOJO_RESULT_BUSY:
+ case MOJO_RESULT_INVALID_ARGUMENT:
+ NOTREACHED();
+ return;
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // Closed by peer.
+ OnCompleted();
+ return;
+ case MOJO_RESULT_SHOULD_WAIT:
+ watcher_.ArmOrNotify();
+ return;
+ case MOJO_RESULT_OK:
+ break;
+ default:
+ // mojo::BeginReadDataRaw() should not return any other values.
+ // Notify the error to the browser by resetting the handle even though
+ // it's in the middle of data transfer.
+ OnCompleted();
+ return;
+ }
+
+ if (bytes_read > 0) {
+ BytesChunk chunk;
+ chunk.Append(static_cast<const char*>(buffer), bytes_read);
+ chunks_.emplace_back(std::move(chunk));
+ }
+ rv = handle_->EndReadData(bytes_read);
+ DCHECK_EQ(rv, MOJO_RESULT_OK);
+ CHECK_GE(remaining_bytes_, bytes_read);
+ remaining_bytes_ -= bytes_read;
+ watcher_.ArmOrNotify();
+ }
+
+ bool is_running() const { return handle_.is_valid(); }
+ bool has_received_all_data() const { return remaining_bytes_ == 0; }
+
+ Vector<BytesChunk> TakeChunks() {
+ DCHECK(!is_running());
+ return std::move(chunks_);
+ }
+
+ private:
+ void OnCompleted() {
+ handle_.reset();
+ watcher_.Cancel();
+ if (!has_received_all_data())
+ chunks_.clear();
+ DCHECK(callback_);
+ std::move(callback_).Run();
+ }
+
+ base::OnceClosure callback_;
+ mojo::ScopedDataPipeConsumerHandle handle_;
+ mojo::SimpleWatcher watcher_;
+
+ Vector<BytesChunk> chunks_;
+ uint64_t remaining_bytes_;
+};
+
+// BundledReceivers is a helper class to wait for the end of reading body and
+// meta data. Lives on the IO thread.
+class BundledReceivers {
+ public:
+ BundledReceivers(mojo::ScopedDataPipeConsumerHandle meta_data_handle,
+ uint64_t meta_data_size,
+ mojo::ScopedDataPipeConsumerHandle body_handle,
+ uint64_t body_size,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : meta_data_(std::move(meta_data_handle), meta_data_size, task_runner),
+ body_(std::move(body_handle), body_size, std::move(task_runner)) {}
+
+ // Starts reading the pipes and invokes |callback| when both are finished.
+ void Start(base::OnceClosure callback) {
+ base::RepeatingClosure wait_all_closure =
+ base::BarrierClosure(2, std::move(callback));
+ meta_data_.Start(wait_all_closure);
+ body_.Start(wait_all_closure);
+ }
+
+ Receiver* meta_data() { return &meta_data_; }
+ Receiver* body() { return &body_; }
+
+ private:
+ Receiver meta_data_;
+ Receiver body_;
+};
+
+// Internal lives on the IO thread. This receives
+// mojom::blink::ServiceWorkerScriptInfo for all installed scripts and then
+// starts reading the body and meta data from the browser. This instance will be
+// kept alive as long as the Mojo's connection is established.
+class Internal : public mojom::blink::ServiceWorkerInstalledScriptsManager {
+ public:
+ // Called on the IO thread.
+ // Creates and binds a new Internal instance to |request|.
+ static void Create(
+ scoped_refptr<ThreadSafeScriptContainer> script_container,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerRequest request,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ mojo::MakeStrongBinding(
+ std::make_unique<Internal>(std::move(script_container),
+ std::move(task_runner)),
+ std::move(request));
+ }
+
+ Internal(scoped_refptr<ThreadSafeScriptContainer> script_container,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : script_container_(std::move(script_container)),
+ task_runner_(std::move(task_runner)),
+ weak_factory_(this) {}
+
+ ~Internal() override {
+ DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
+ // Wake up a waiting thread so it does not wait forever. If the script has
+ // not been added yet, that means something went wrong. From here,
+ // script_container_->Wait() will return false if the script hasn't been
+ // added yet.
+ script_container_->OnAllDataAddedOnIOThread();
+ }
+
+ // Implements mojom::blink::ServiceWorkerInstalledScriptsManager.
+ // Called on the IO thread.
+ void TransferInstalledScript(
+ mojom::blink::ServiceWorkerScriptInfoPtr script_info) override {
+ DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
+ KURL script_url(script_info->script_url);
+ auto receivers = std::make_unique<BundledReceivers>(
+ std::move(script_info->meta_data), script_info->meta_data_size,
+ std::move(script_info->body), script_info->body_size, task_runner_);
+ receivers->Start(WTF::Bind(&Internal::OnScriptReceived,
+ weak_factory_.GetWeakPtr(),
+ std::move(script_info)));
+ DCHECK(!running_receivers_.Contains(script_url));
+ running_receivers_.insert(script_url, std::move(receivers));
+ }
+
+ // Called on the IO thread.
+ void OnScriptReceived(mojom::blink::ServiceWorkerScriptInfoPtr script_info) {
+ DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
+ auto iter = running_receivers_.find(script_info->script_url);
+ DCHECK(iter != running_receivers_.end());
+ std::unique_ptr<BundledReceivers> receivers = std::move(iter->value);
+ DCHECK(receivers);
+ if (!receivers->body()->has_received_all_data() ||
+ !receivers->meta_data()->has_received_all_data()) {
+ script_container_->AddOnIOThread(script_info->script_url,
+ nullptr /* data */);
+ running_receivers_.erase(iter);
+ return;
+ }
+
+ auto script_data = RawScriptData::Create(
+ script_info->encoding, receivers->body()->TakeChunks(),
+ receivers->meta_data()->TakeChunks());
+ for (const auto& entry : script_info->headers)
+ script_data->AddHeader(entry.key, entry.value);
+ script_container_->AddOnIOThread(script_info->script_url,
+ std::move(script_data));
+ running_receivers_.erase(iter);
+ }
+
+ private:
+ THREAD_CHECKER(io_thread_checker_);
+ HashMap<KURL, std::unique_ptr<BundledReceivers>> running_receivers_;
+ scoped_refptr<ThreadSafeScriptContainer> script_container_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ base::WeakPtrFactory<Internal> weak_factory_;
+};
+
+} // namespace
+
ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager(
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager> manager)
- : manager_(std::move(manager)) {
- DCHECK(manager_);
+ const Vector<KURL>& installed_urls,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerRequest manager_request,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHostPtrInfo
+ manager_host_ptr,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+ : script_container_(base::MakeRefCounted<ThreadSafeScriptContainer>()),
+ manager_host_(
+ mojom::blink::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr::
+ Create(mojom::blink::ServiceWorkerInstalledScriptsManagerHostPtr(
+ std::move(manager_host_ptr)))) {
+ // We're on the main thread now, but |installed_urls_| will be accessed on the
+ // worker thread later, so make a deep copy of |url| as key.
+ for (const KURL& url : installed_urls)
+ installed_urls_.insert(url.Copy());
+ io_task_runner->PostTask(
+ FROM_HERE, ConvertToBaseCallback(CrossThreadBind(
+ &Internal::Create, script_container_,
+ WTF::Passed(std::move(manager_request)), io_task_runner)));
}
bool ServiceWorkerInstalledScriptsManager::IsScriptInstalled(
const KURL& script_url) const {
- return manager_->IsScriptInstalled(script_url);
+ return installed_urls_.Contains(script_url);
}
-InstalledScriptsManager::ScriptStatus
-ServiceWorkerInstalledScriptsManager::GetScriptData(
- const KURL& script_url,
- InstalledScriptsManager::ScriptData* out_script_data) {
+std::unique_ptr<InstalledScriptsManager::ScriptData>
+ServiceWorkerInstalledScriptsManager::GetScriptData(const KURL& script_url) {
DCHECK(!IsMainThread());
+ if (!IsScriptInstalled(script_url))
+ return nullptr;
+
// This blocks until the script is received from the browser.
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager::RawScriptData>
- raw_script_data = manager_->GetRawScriptData(script_url);
- DCHECK(raw_script_data);
- if (!raw_script_data->IsValid()) {
- *out_script_data = InstalledScriptsManager::ScriptData();
- return ScriptStatus::kFailed;
- }
+ std::unique_ptr<RawScriptData> raw_script_data = GetRawScriptData(script_url);
+ if (!raw_script_data)
+ return nullptr;
// This is from WorkerClassicScriptLoader::DidReceiveData.
std::unique_ptr<TextResourceDecoder> decoder =
@@ -48,7 +281,7 @@ ServiceWorkerInstalledScriptsManager::GetScriptData(
StringBuilder source_text_builder;
for (const auto& chunk : raw_script_data->ScriptTextChunks())
- source_text_builder.Append(decoder->Decode(chunk.Data(), chunk.size()));
+ source_text_builder.Append(decoder->Decode(chunk.data(), chunk.size()));
std::unique_ptr<Vector<char>> meta_data;
if (raw_script_data->MetaDataChunks().size() > 0) {
@@ -58,14 +291,43 @@ ServiceWorkerInstalledScriptsManager::GetScriptData(
meta_data = std::make_unique<Vector<char>>();
meta_data->ReserveInitialCapacity(total_metadata_size);
for (const auto& chunk : raw_script_data->MetaDataChunks())
- meta_data->Append(chunk.Data(), chunk.size());
+ meta_data->Append(chunk.data(), chunk.size());
}
- InstalledScriptsManager::ScriptData script_data(
+ return std::make_unique<InstalledScriptsManager::ScriptData>(
script_url, source_text_builder.ToString(), std::move(meta_data),
raw_script_data->TakeHeaders());
- *out_script_data = std::move(script_data);
- return ScriptStatus::kSuccess;
+}
+
+std::unique_ptr<RawScriptData>
+ServiceWorkerInstalledScriptsManager::GetRawScriptData(const KURL& script_url) {
+ ThreadSafeScriptContainer::ScriptStatus status =
+ script_container_->GetStatusOnWorkerThread(script_url);
+ // If the script has already been taken, request the browser to send the
+ // script.
+ if (status == ThreadSafeScriptContainer::ScriptStatus::kTaken) {
+ script_container_->ResetOnWorkerThread(script_url);
+ (*manager_host_)->RequestInstalledScript(script_url);
+ status = script_container_->GetStatusOnWorkerThread(script_url);
+ }
+
+ // If the script has not been received at this point, wait for arrival by
+ // blocking the worker thread.
+ if (status == ThreadSafeScriptContainer::ScriptStatus::kPending) {
+ // Wait for arrival of the script.
+ const bool success = script_container_->WaitOnWorkerThread(script_url);
+ // It can fail due to an error on Mojo pipes.
+ if (!success)
+ return nullptr;
+ status = script_container_->GetStatusOnWorkerThread(script_url);
+ DCHECK_NE(ThreadSafeScriptContainer::ScriptStatus::kPending, status);
+ }
+
+ if (status == ThreadSafeScriptContainer::ScriptStatus::kFailed)
+ return nullptr;
+ DCHECK_EQ(ThreadSafeScriptContainer::ScriptStatus::kReceived, status);
+
+ return script_container_->TakeOnWorkerThread(script_url);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h
index 91e909807ca..1312019537f 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h
@@ -5,29 +5,47 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_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/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h"
#include "third_party/blink/renderer/core/workers/installed_scripts_manager.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
// ServiceWorkerInstalledScriptsManager provides the main script and imported
// scripts of an installed service worker. The scripts are streamed from the
// browser process in parallel with worker thread initialization.
-class ServiceWorkerInstalledScriptsManager final
+class MODULES_EXPORT ServiceWorkerInstalledScriptsManager
: public InstalledScriptsManager {
public:
- explicit ServiceWorkerInstalledScriptsManager(
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager>);
+ ServiceWorkerInstalledScriptsManager(
+ const Vector<KURL>& installed_urls,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerRequest,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHostPtrInfo,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
+ virtual ~ServiceWorkerInstalledScriptsManager() = default;
// InstalledScriptsManager implementation.
bool IsScriptInstalled(const KURL& script_url) const override;
- ScriptStatus GetScriptData(const KURL& script_url,
- ScriptData* out_script_data) override;
+ std::unique_ptr<ScriptData> GetScriptData(const KURL& script_url) override;
private:
- std::unique_ptr<WebServiceWorkerInstalledScriptsManager> manager_;
+ friend class ServiceWorkerInstalledScriptsManagerTest;
+
+ std::unique_ptr<ThreadSafeScriptContainer::RawScriptData> GetRawScriptData(
+ const KURL& script_url);
+
+ HashSet<KURL> installed_urls_;
+ scoped_refptr<ThreadSafeScriptContainer> script_container_;
+ scoped_refptr<
+ mojom::blink::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr>
+ manager_host_;
};
} // namespace blink
-#endif // WorkerInstalledScriptsManager_h
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_H_
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
new file mode 100644
index 00000000000..2c41d7c7168
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
@@ -0,0 +1,428 @@
+// 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 "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
+
+#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/waitable_event.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+namespace {
+
+class BrowserSideSender
+ : mojom::blink::ServiceWorkerInstalledScriptsManagerHost {
+ public:
+ BrowserSideSender() : binding_(this) {}
+ ~BrowserSideSender() override = default;
+
+ mojom::blink::ServiceWorkerInstalledScriptsInfoPtr CreateAndBind(
+ const Vector<KURL>& installed_urls) {
+ EXPECT_FALSE(manager_.is_bound());
+ EXPECT_FALSE(body_handle_.is_valid());
+ EXPECT_FALSE(meta_data_handle_.is_valid());
+ auto scripts_info = mojom::blink::ServiceWorkerInstalledScriptsInfo::New();
+ scripts_info->installed_urls = installed_urls;
+ scripts_info->manager_request = mojo::MakeRequest(&manager_);
+ binding_.Bind(mojo::MakeRequest(&scripts_info->manager_host_ptr));
+ return scripts_info;
+ }
+
+ void TransferInstalledScript(const KURL& script_url,
+ const String& encoding,
+ const HashMap<String, String>& headers,
+ int64_t body_size,
+ int64_t meta_data_size) {
+ EXPECT_FALSE(body_handle_.is_valid());
+ EXPECT_FALSE(meta_data_handle_.is_valid());
+ auto script_info = mojom::blink::ServiceWorkerScriptInfo::New();
+ script_info->script_url = script_url;
+ script_info->encoding = encoding;
+ script_info->headers = headers;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(nullptr, &body_handle_, &script_info->body));
+ EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(nullptr, &meta_data_handle_,
+ &script_info->meta_data));
+ script_info->body_size = body_size;
+ script_info->meta_data_size = meta_data_size;
+ manager_->TransferInstalledScript(std::move(script_info));
+ }
+
+ void PushBody(const std::string& data) {
+ PushDataPipe(data, body_handle_.get());
+ }
+
+ void PushMetaData(const std::string& data) {
+ PushDataPipe(data, meta_data_handle_.get());
+ }
+
+ void FinishTransferBody() { body_handle_.reset(); }
+
+ void FinishTransferMetaData() { meta_data_handle_.reset(); }
+
+ void ResetManager() { manager_.reset(); }
+
+ void WaitForRequestInstalledScript(const KURL& script_url) {
+ waiting_requested_url_ = script_url;
+ base::RunLoop loop;
+ requested_script_closure_ = loop.QuitClosure();
+ loop.Run();
+ }
+
+ private:
+ void RequestInstalledScript(const KURL& script_url) override {
+ EXPECT_EQ(waiting_requested_url_, script_url);
+ ASSERT_TRUE(requested_script_closure_);
+ std::move(requested_script_closure_).Run();
+ }
+
+ void PushDataPipe(const std::string& data,
+ const mojo::DataPipeProducerHandle& handle) {
+ // Send |data| with null terminator.
+ ASSERT_TRUE(handle.is_valid());
+ uint32_t written_bytes = data.size() + 1;
+ MojoResult rv = handle.WriteData(data.c_str(), &written_bytes,
+ MOJO_WRITE_DATA_FLAG_NONE);
+ ASSERT_EQ(MOJO_RESULT_OK, rv);
+ ASSERT_EQ(data.size() + 1, written_bytes);
+ }
+
+ base::OnceClosure requested_script_closure_;
+ KURL waiting_requested_url_;
+
+ mojom::blink::ServiceWorkerInstalledScriptsManagerPtr manager_;
+ mojo::Binding<mojom::blink::ServiceWorkerInstalledScriptsManagerHost>
+ binding_;
+
+ mojo::ScopedDataPipeProducerHandle body_handle_;
+ mojo::ScopedDataPipeProducerHandle meta_data_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserSideSender);
+};
+
+CrossThreadHTTPHeaderMapData ToCrossThreadHTTPHeaderMapData(
+ const HashMap<String, String>& headers) {
+ CrossThreadHTTPHeaderMapData data;
+ for (const auto& entry : headers)
+ data.emplace_back(entry.key, entry.value);
+ return data;
+}
+
+} // namespace
+
+class ServiceWorkerInstalledScriptsManagerTest : public testing::Test {
+ public:
+ ServiceWorkerInstalledScriptsManagerTest()
+ : io_thread_(Platform::Current()->CreateThread(
+ ThreadCreationParams(WebThreadType::kTestThread)
+ .SetThreadNameForTest("io thread"))),
+ worker_thread_(Platform::Current()->CreateThread(
+ ThreadCreationParams(WebThreadType::kTestThread)
+ .SetThreadNameForTest("worker thread"))) {}
+
+ protected:
+ using RawScriptData = ThreadSafeScriptContainer::RawScriptData;
+
+ void CreateInstalledScriptsManager(
+ mojom::blink::ServiceWorkerInstalledScriptsInfoPtr
+ installed_scripts_info) {
+ installed_scripts_manager_ =
+ std::make_unique<ServiceWorkerInstalledScriptsManager>(
+ std::move(installed_scripts_info->installed_urls),
+ std::move(installed_scripts_info->manager_request),
+ std::move(installed_scripts_info->manager_host_ptr),
+ io_thread_->GetTaskRunner());
+ }
+
+ WaitableEvent* IsScriptInstalledOnWorkerThread(const String& script_url,
+ bool* out_installed) {
+ PostCrossThreadTask(
+ *worker_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](ServiceWorkerInstalledScriptsManager* installed_scripts_manager,
+ const String& script_url, bool* out_installed,
+ WaitableEvent* waiter) {
+ *out_installed = installed_scripts_manager->IsScriptInstalled(
+ KURL(script_url));
+ waiter->Signal();
+ },
+ CrossThreadUnretained(installed_scripts_manager_.get()), script_url,
+ CrossThreadUnretained(out_installed),
+ CrossThreadUnretained(&worker_waiter_)));
+ return &worker_waiter_;
+ }
+
+ WaitableEvent* GetRawScriptDataOnWorkerThread(
+ const String& script_url,
+ std::unique_ptr<RawScriptData>* out_data) {
+ PostCrossThreadTask(
+ *worker_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ &ServiceWorkerInstalledScriptsManagerTest::CallGetRawScriptData,
+ CrossThreadUnretained(this), script_url,
+ CrossThreadUnretained(out_data),
+ CrossThreadUnretained(&worker_waiter_)));
+ return &worker_waiter_;
+ }
+
+ private:
+ void CallGetRawScriptData(const String& script_url,
+ std::unique_ptr<RawScriptData>* out_data,
+ WaitableEvent* waiter) {
+ *out_data = installed_scripts_manager_->GetRawScriptData(KURL(script_url));
+ waiter->Signal();
+ }
+
+ std::unique_ptr<Thread> io_thread_;
+ std::unique_ptr<Thread> worker_thread_;
+
+ WaitableEvent worker_waiter_;
+
+ std::unique_ptr<ServiceWorkerInstalledScriptsManager>
+ installed_scripts_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerInstalledScriptsManagerTest);
+};
+
+TEST_F(ServiceWorkerInstalledScriptsManagerTest, GetRawScriptData) {
+ const KURL kScriptUrl("https://example.com/installed1.js");
+ const KURL kUnknownScriptUrl("https://example.com/not_installed.js");
+
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
+
+ {
+ bool result = false;
+ IsScriptInstalledOnWorkerThread(kScriptUrl, &result)->Wait();
+ // IsScriptInstalled returns correct answer even before script transfer
+ // hasn't been started yet.
+ EXPECT_TRUE(result);
+ }
+
+ {
+ bool result = true;
+ IsScriptInstalledOnWorkerThread(kUnknownScriptUrl, &result)->Wait();
+ // IsScriptInstalled returns correct answer even before script transfer
+ // hasn't been started yet.
+ EXPECT_FALSE(result);
+ }
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ const std::string kExpectedBody = "This is a script body.";
+ const std::string kExpectedMetaData = "This is a meta data.";
+ const String kScriptInfoEncoding("utf8");
+ const HashMap<String, String> kScriptInfoHeaders(
+ {{"Cache-Control", "no-cache"}, {"User-Agent", "Chrome"}});
+
+ WaitableEvent* get_raw_script_data_waiter =
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
+
+ // Start transferring the script. +1 for null terminator.
+ sender.TransferInstalledScript(kScriptUrl, kScriptInfoEncoding,
+ kScriptInfoHeaders, kExpectedBody.size() + 1,
+ kExpectedMetaData.size() + 1);
+ sender.PushBody(kExpectedBody);
+ sender.PushMetaData(kExpectedMetaData);
+ // GetRawScriptData should be blocked until body and meta data transfer are
+ // finished.
+ EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
+ sender.FinishTransferBody();
+ sender.FinishTransferMetaData();
+
+ // Wait for the script's arrival.
+ get_raw_script_data_waiter->Wait();
+ EXPECT_TRUE(script_data);
+ ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
+ ASSERT_EQ(kExpectedBody.size() + 1,
+ script_data->ScriptTextChunks()[0].size());
+ EXPECT_STREQ(kExpectedBody.data(),
+ script_data->ScriptTextChunks()[0].data());
+ ASSERT_EQ(1u, script_data->MetaDataChunks().size());
+ ASSERT_EQ(kExpectedMetaData.size() + 1,
+ script_data->MetaDataChunks()[0].size());
+ EXPECT_STREQ(kExpectedMetaData.data(),
+ script_data->MetaDataChunks()[0].data());
+ EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding());
+ EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders),
+ *(script_data->TakeHeaders()));
+ }
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ const std::string kExpectedBody = "This is another script body.";
+ const std::string kExpectedMetaData = "This is another meta data.";
+ const String kScriptInfoEncoding("ASCII");
+ const HashMap<String, String> kScriptInfoHeaders(
+ {{"Connection", "keep-alive"}, {"Content-Length", "512"}});
+
+ // Request the same script again.
+ WaitableEvent* get_raw_script_data_waiter =
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
+
+ // It should call a Mojo IPC "RequestInstalledScript()" to the browser.
+ sender.WaitForRequestInstalledScript(kScriptUrl);
+
+ // Start transferring the script. +1 for null terminator.
+ sender.TransferInstalledScript(kScriptUrl, kScriptInfoEncoding,
+ kScriptInfoHeaders, kExpectedBody.size() + 1,
+ kExpectedMetaData.size() + 1);
+ sender.PushBody(kExpectedBody);
+ sender.PushMetaData(kExpectedMetaData);
+ // GetRawScriptData should be blocked until body and meta data transfer are
+ // finished.
+ EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
+ sender.FinishTransferBody();
+ sender.FinishTransferMetaData();
+
+ // Wait for the script's arrival.
+ get_raw_script_data_waiter->Wait();
+ EXPECT_TRUE(script_data);
+ ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
+ ASSERT_EQ(kExpectedBody.size() + 1,
+ script_data->ScriptTextChunks()[0].size());
+ EXPECT_STREQ(kExpectedBody.data(),
+ script_data->ScriptTextChunks()[0].data());
+ ASSERT_EQ(1u, script_data->MetaDataChunks().size());
+ ASSERT_EQ(kExpectedMetaData.size() + 1,
+ script_data->MetaDataChunks()[0].size());
+ EXPECT_STREQ(kExpectedMetaData.data(),
+ script_data->MetaDataChunks()[0].data());
+ EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding());
+ EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders),
+ *(script_data->TakeHeaders()));
+ }
+}
+
+TEST_F(ServiceWorkerInstalledScriptsManagerTest, EarlyDisconnectionBody) {
+ const KURL kScriptUrl("https://example.com/installed1.js");
+ const KURL kUnknownScriptUrl("https://example.com/not_installed.js");
+
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ const std::string kExpectedBody = "This is a script body.";
+ const std::string kExpectedMetaData = "This is a meta data.";
+ WaitableEvent* get_raw_script_data_waiter =
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
+
+ // Start transferring the script.
+ // Body is expected to be 100 bytes larger than kExpectedBody, but sender
+ // only sends kExpectedBody and a null byte (kExpectedBody.size() + 1 bytes
+ // in total).
+ sender.TransferInstalledScript(
+ kScriptUrl, String::FromUTF8("utf8"), HashMap<String, String>(),
+ kExpectedBody.size() + 100, kExpectedMetaData.size() + 1);
+ sender.PushBody(kExpectedBody);
+ sender.PushMetaData(kExpectedMetaData);
+ // GetRawScriptData should be blocked until body and meta data transfer are
+ // finished.
+ EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
+ sender.FinishTransferBody();
+ sender.FinishTransferMetaData();
+
+ // Wait for the script's arrival.
+ get_raw_script_data_waiter->Wait();
+ // |script_data| should be null since the data pipe for body
+ // gets disconnected during sending.
+ EXPECT_FALSE(script_data);
+ }
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
+ // |script_data| should be null since the data wasn't received on the
+ // renderer process.
+ EXPECT_FALSE(script_data);
+ }
+}
+
+TEST_F(ServiceWorkerInstalledScriptsManagerTest, EarlyDisconnectionMetaData) {
+ const KURL kScriptUrl("https://example.com/installed1.js");
+ const KURL kUnknownScriptUrl("https://example.com/not_installed.js");
+
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ const std::string kExpectedBody = "This is a script body.";
+ const std::string kExpectedMetaData = "This is a meta data.";
+ WaitableEvent* get_raw_script_data_waiter =
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
+
+ // Start transferring the script.
+ // Meta data is expected to be 100 bytes larger than kExpectedMetaData, but
+ // sender only sends kExpectedMetaData and a null byte
+ // (kExpectedMetaData.size() + 1 bytes in total).
+ sender.TransferInstalledScript(
+ kScriptUrl, String::FromUTF8("utf8"), HashMap<String, String>(),
+ kExpectedBody.size() + 1, kExpectedMetaData.size() + 100);
+ sender.PushBody(kExpectedBody);
+ sender.PushMetaData(kExpectedMetaData);
+ // GetRawScriptData should be blocked until body and meta data transfer are
+ // finished.
+ EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
+ sender.FinishTransferBody();
+ sender.FinishTransferMetaData();
+
+ // Wait for the script's arrival.
+ get_raw_script_data_waiter->Wait();
+ // |script_data| should be null since the data pipe for meta data gets
+ // disconnected during sending.
+ EXPECT_FALSE(script_data);
+ }
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
+ // |script_data| should be null since the data wasn't received on the
+ // renderer process.
+ EXPECT_FALSE(script_data);
+ }
+}
+
+TEST_F(ServiceWorkerInstalledScriptsManagerTest, EarlyDisconnectionManager) {
+ const KURL kScriptUrl("https://example.com/installed1.js");
+ const KURL kUnknownScriptUrl("https://example.com/not_installed.js");
+
+ BrowserSideSender sender;
+ CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ WaitableEvent* get_raw_script_data_waiter =
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
+
+ // Reset the Mojo connection before sending the script.
+ EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
+ sender.ResetManager();
+
+ // Wait for the script's arrival.
+ get_raw_script_data_waiter->Wait();
+ // |script_data| should be nullptr since no data will arrive.
+ EXPECT_FALSE(script_data);
+ }
+
+ {
+ std::unique_ptr<RawScriptData> script_data;
+ // This should not be blocked because data will not arrive anymore.
+ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
+ // |script_data| should be null since the data wasn't received on the
+ // renderer process.
+ EXPECT_FALSE(script_data);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
index f65cf9c6ce9..bb515811db5 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
@@ -40,28 +40,22 @@ void ServiceWorkerRegistration::DispatchUpdateFoundEvent() {
DispatchEvent(*Event::Create(EventTypeNames::updatefound));
}
-void ServiceWorkerRegistration::SetInstalling(
- std::unique_ptr<WebServiceWorker::Handle> handle) {
+void ServiceWorkerRegistration::SetInstalling(WebServiceWorkerObjectInfo info) {
if (!GetExecutionContext())
return;
- installing_ = ServiceWorker::From(GetExecutionContext(),
- base::WrapUnique(handle.release()));
+ installing_ = ServiceWorker::From(GetExecutionContext(), std::move(info));
}
-void ServiceWorkerRegistration::SetWaiting(
- std::unique_ptr<WebServiceWorker::Handle> handle) {
+void ServiceWorkerRegistration::SetWaiting(WebServiceWorkerObjectInfo info) {
if (!GetExecutionContext())
return;
- waiting_ = ServiceWorker::From(GetExecutionContext(),
- base::WrapUnique(handle.release()));
+ waiting_ = ServiceWorker::From(GetExecutionContext(), std::move(info));
}
-void ServiceWorkerRegistration::SetActive(
- std::unique_ptr<WebServiceWorker::Handle> handle) {
+void ServiceWorkerRegistration::SetActive(WebServiceWorkerObjectInfo info) {
if (!GetExecutionContext())
return;
- active_ = ServiceWorker::From(GetExecutionContext(),
- base::WrapUnique(handle.release()));
+ active_ = ServiceWorker::From(GetExecutionContext(), std::move(info));
}
ServiceWorkerRegistration* ServiceWorkerRegistration::GetOrCreate(
@@ -103,16 +97,13 @@ String ServiceWorkerRegistration::updateViaCache() const {
}
ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
- ServiceWorkerContainerClient* client =
- ServiceWorkerContainerClient::From(GetExecutionContext());
- if (!client || !client->Provider()) {
+ if (!GetExecutionContext()) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(DOMExceptionCode::kInvalidStateError,
"Failed to update a ServiceWorkerRegistration: No "
"associated provider is available."));
}
-
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
handle_->Registration()->Update(
@@ -123,9 +114,7 @@ ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
}
ScriptPromise ServiceWorkerRegistration::unregister(ScriptState* script_state) {
- ServiceWorkerContainerClient* client =
- ServiceWorkerContainerClient::From(GetExecutionContext());
- if (!client || !client->Provider()) {
+ if (!GetExecutionContext()) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(DOMExceptionCode::kInvalidStateError,
@@ -133,7 +122,6 @@ ScriptPromise ServiceWorkerRegistration::unregister(ScriptState* script_state) {
"ServiceWorkerRegistration: No "
"associated provider is available."));
}
-
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
handle_->Registration()->Unregister(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
index fbb096a32ad..70d5bbfed0a 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h
@@ -8,6 +8,7 @@
#include <memory>
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration_proxy.h"
+#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
@@ -54,9 +55,9 @@ class ServiceWorkerRegistration final
// WebServiceWorkerRegistrationProxy overrides.
void DispatchUpdateFoundEvent() override;
- void SetInstalling(std::unique_ptr<WebServiceWorker::Handle>) override;
- void SetWaiting(std::unique_ptr<WebServiceWorker::Handle>) override;
- void SetActive(std::unique_ptr<WebServiceWorker::Handle>) override;
+ void SetInstalling(WebServiceWorkerObjectInfo) override;
+ void SetWaiting(WebServiceWorkerObjectInfo) override;
+ void SetActive(WebServiceWorkerObjectInfo) override;
// Returns an existing registration object for the handle if it exists.
// Otherwise, returns a new registration object.
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
index a50faeb704d..21795936964 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
@@ -3,9 +3,7 @@
// found in the LICENSE file.
// https://w3c.github.io/ServiceWorker/#enumdef-serviceworkerupdateviacache
-[
- RuntimeEnabled=ServiceWorkerUpdateViaCache
-] enum ServiceWorkerUpdateViaCache {
+enum ServiceWorkerUpdateViaCache {
"imports",
"all",
"none"
@@ -23,7 +21,7 @@
readonly attribute NavigationPreloadManager navigationPreload;
readonly attribute USVString scope;
- [RuntimeEnabled=ServiceWorkerUpdateViaCache] readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
+ readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
[CallWith=ScriptState] Promise<ServiceWorkerRegistration> update();
[CallWith=ScriptState] Promise<boolean> unregister();
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
index 1cec901709b..338ac091918 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
@@ -47,8 +47,8 @@ ServiceWorkerThread::ServiceWorkerThread(
mojom::blink::CacheStoragePtrInfo cache_storage_info)
: WorkerThread(*global_scope_proxy),
global_scope_proxy_(global_scope_proxy),
- worker_backing_thread_(WorkerBackingThread::Create(
- WebThreadCreationParams(GetThreadType()))),
+ worker_backing_thread_(
+ WorkerBackingThread::Create(ThreadCreationParams(GetThreadType()))),
installed_scripts_manager_(std::move(installed_scripts_manager)),
cache_storage_info_(std::move(cache_storage_info)) {}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
index d3849e40e7e..6e9f32087dd 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
@@ -16,19 +16,39 @@
#include "third_party/blink/renderer/core/workers/worker_location.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_error.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
namespace blink {
-ServiceWorkerWindowClient* ServiceWorkerWindowClient::Take(
- ScriptPromiseResolver*,
- std::unique_ptr<WebServiceWorkerClientInfo> web_client) {
- return web_client ? ServiceWorkerWindowClient::Create(*web_client) : nullptr;
+namespace {
+
+void DidFocus(ScriptPromiseResolver* resolver,
+ mojom::blink::ServiceWorkerClientInfoPtr client) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
+ }
+
+ if (!client) {
+ resolver->Reject(ServiceWorkerError::GetException(
+ resolver, mojom::blink::ServiceWorkerErrorType::kNotFound,
+ "The client was not found."));
+ return;
+ }
+ resolver->Resolve(ServiceWorkerWindowClient::Create(*client));
}
+} // namespace
+
ServiceWorkerWindowClient* ServiceWorkerWindowClient::Create(
const WebServiceWorkerClientInfo& info) {
+ DCHECK_EQ(mojom::blink::ServiceWorkerClientType::kWindow, info.client_type);
+ return new ServiceWorkerWindowClient(info);
+}
+
+ServiceWorkerWindowClient* ServiceWorkerWindowClient::Create(
+ const mojom::blink::ServiceWorkerClientInfo& info) {
+ DCHECK_EQ(mojom::blink::ServiceWorkerClientType::kWindow, info.client_type);
return new ServiceWorkerWindowClient(info);
}
@@ -38,6 +58,12 @@ ServiceWorkerWindowClient::ServiceWorkerWindowClient(
page_visibility_state_(info.page_visibility_state),
is_focused_(info.is_focused) {}
+ServiceWorkerWindowClient::ServiceWorkerWindowClient(
+ const mojom::blink::ServiceWorkerClientInfo& info)
+ : ServiceWorkerClient(info),
+ page_visibility_state_(info.page_visibility_state),
+ is_focused_(info.is_focused) {}
+
ServiceWorkerWindowClient::~ServiceWorkerWindowClient() = default;
String ServiceWorkerWindowClient::visibilityState() const {
@@ -56,10 +82,7 @@ ScriptPromise ServiceWorkerWindowClient::focus(ScriptState* script_state) {
ExecutionContext::From(script_state)->ConsumeWindowInteraction();
ServiceWorkerGlobalScopeClient::From(ExecutionContext::From(script_state))
- ->Focus(Uuid(),
- std::make_unique<CallbackPromiseAdapter<ServiceWorkerWindowClient,
- ServiceWorkerError>>(
- resolver));
+ ->Focus(Uuid(), WTF::Bind(&DidFocus, WrapPersistent(resolver)));
return promise;
}
@@ -82,8 +105,8 @@ ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state,
return promise;
}
- ServiceWorkerGlobalScopeClient::From(context)->Navigate(
- Uuid(), parsed_url, std::make_unique<NavigateClientCallback>(resolver));
+ ServiceWorkerGlobalScopeClient::From(context)->Navigate(Uuid(), parsed_url,
+ resolver);
return promise;
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
index 1b81d633637..863d318f4b2 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h
@@ -14,7 +14,6 @@
namespace blink {
-class ScriptPromiseResolver;
class ScriptState;
class MODULES_EXPORT ServiceWorkerWindowClient final
@@ -22,14 +21,9 @@ class MODULES_EXPORT ServiceWorkerWindowClient final
DEFINE_WRAPPERTYPEINFO();
public:
- // To be used by CallbackPromiseAdapter.
- using WebType = std::unique_ptr<WebServiceWorkerClientInfo>;
-
- static ServiceWorkerWindowClient* Take(
- ScriptPromiseResolver*,
- std::unique_ptr<WebServiceWorkerClientInfo>);
-
static ServiceWorkerWindowClient* Create(const WebServiceWorkerClientInfo&);
+ static ServiceWorkerWindowClient* Create(
+ const mojom::blink::ServiceWorkerClientInfo&);
~ServiceWorkerWindowClient() override;
// WindowClient.idl
@@ -42,6 +36,8 @@ class MODULES_EXPORT ServiceWorkerWindowClient final
private:
explicit ServiceWorkerWindowClient(const WebServiceWorkerClientInfo&);
+ explicit ServiceWorkerWindowClient(
+ const mojom::blink::ServiceWorkerClientInfo&);
mojom::PageVisibilityState page_visibility_state_;
bool is_focused_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.cc
deleted file mode 100644
index 2400813dc70..00000000000
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.cc
+++ /dev/null
@@ -1,43 +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 "third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h"
-
-#include <memory>
-
-#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_error.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client.h"
-#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
-
-namespace blink {
-
-void NavigateClientCallback::OnSuccess(
- std::unique_ptr<WebServiceWorkerClientInfo> client_info) {
- if (!resolver_->GetExecutionContext() ||
- resolver_->GetExecutionContext()->IsContextDestroyed())
- return;
- resolver_->Resolve(ServiceWorkerWindowClient::Take(
- resolver_.Get(), base::WrapUnique(client_info.release())));
-}
-
-void NavigateClientCallback::OnError(const WebServiceWorkerError& error) {
- if (!resolver_->GetExecutionContext() ||
- resolver_->GetExecutionContext()->IsContextDestroyed())
- return;
-
- if (error.error_type == mojom::blink::ServiceWorkerErrorType::kNavigation) {
- ScriptState::Scope scope(resolver_->GetScriptState());
- resolver_->Reject(V8ThrowException::CreateTypeError(
- resolver_->GetScriptState()->GetIsolate(), error.message));
- return;
- }
-
- resolver_->Reject(ServiceWorkerError::Take(resolver_.Get(), error));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h
deleted file mode 100644
index cf82b10dc2e..00000000000
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client_callback.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_WINDOW_CLIENT_CALLBACK_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_WINDOW_CLIENT_CALLBACK_H_
-
-#include "base/macros.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-class ScriptPromiseResolver;
-
-class NavigateClientCallback : public WebServiceWorkerClientCallbacks {
- public:
- explicit NavigateClientCallback(ScriptPromiseResolver* resolver)
- : resolver_(resolver) {}
-
- void OnSuccess(std::unique_ptr<WebServiceWorkerClientInfo>) override;
- void OnError(const WebServiceWorkerError&) override;
-
- private:
- Persistent<ScriptPromiseResolver> resolver_;
- DISALLOW_COPY_AND_ASSIGN(NavigateClientCallback);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_WINDOW_CLIENT_CALLBACK_H_
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc
new file mode 100644
index 00000000000..4d0db13a062
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace blink {
+
+// static
+std::unique_ptr<ThreadSafeScriptContainer::RawScriptData>
+ThreadSafeScriptContainer::RawScriptData::Create(const String& encoding,
+ Vector<BytesChunk> script_text,
+ Vector<BytesChunk> meta_data) {
+ return base::WrapUnique(new RawScriptData(encoding, std::move(script_text),
+ std::move(meta_data)));
+}
+
+ThreadSafeScriptContainer::RawScriptData::RawScriptData(
+ const String& encoding,
+ Vector<BytesChunk> script_text,
+ Vector<BytesChunk> meta_data)
+ : encoding_(encoding.IsolatedCopy()),
+ script_text_(std::move(script_text)),
+ meta_data_(std::move(meta_data)),
+ headers_(std::make_unique<CrossThreadHTTPHeaderMapData>()) {}
+
+ThreadSafeScriptContainer::RawScriptData::~RawScriptData() = default;
+
+void ThreadSafeScriptContainer::RawScriptData::AddHeader(const String& key,
+ const String& value) {
+ headers_->emplace_back(key.IsolatedCopy(), value.IsolatedCopy());
+}
+
+ThreadSafeScriptContainer::ThreadSafeScriptContainer()
+ : waiting_cv_(mutex_), are_all_data_added_(false) {}
+
+void ThreadSafeScriptContainer::AddOnIOThread(
+ const KURL& url,
+ std::unique_ptr<RawScriptData> data) {
+ MutexLocker locker(mutex_);
+ DCHECK_EQ(script_data_.end(), script_data_.find(url));
+ ScriptStatus status = data ? ScriptStatus::kReceived : ScriptStatus::kFailed;
+ // |script_data_| is also accessed on the worker thread, so make a deep copy
+ // of |url| as key.
+ script_data_.Set(url.Copy(), std::make_pair(status, std::move(data)));
+ if (url == waiting_url_)
+ waiting_cv_.Signal();
+}
+
+ThreadSafeScriptContainer::ScriptStatus
+ThreadSafeScriptContainer::GetStatusOnWorkerThread(const KURL& url) {
+ MutexLocker locker(mutex_);
+ auto it = script_data_.find(url);
+ if (it == script_data_.end())
+ return ScriptStatus::kPending;
+ return it->value.first;
+}
+
+void ThreadSafeScriptContainer::ResetOnWorkerThread(const KURL& url) {
+ MutexLocker locker(mutex_);
+ script_data_.erase(url);
+}
+
+bool ThreadSafeScriptContainer::WaitOnWorkerThread(const KURL& url) {
+ MutexLocker locker(mutex_);
+ DCHECK(!waiting_url_.IsValid())
+ << "The script container is unexpectedly shared among worker threads.";
+ // |waiting_url_| is also accessed on the IO thread later, so make a deep copy
+ // of |url|.
+ waiting_url_ = url.Copy();
+ while (script_data_.find(url) == script_data_.end()) {
+ // If waiting script hasn't been added yet though all data are received,
+ // that means something went wrong.
+ if (are_all_data_added_) {
+ waiting_url_ = KURL();
+ return false;
+ }
+ // This is possible to be waken up spuriously, so that it's necessary to
+ // check if the entry is really added.
+ waiting_cv_.Wait();
+ }
+ waiting_url_ = KURL();
+ return true;
+}
+
+std::unique_ptr<ThreadSafeScriptContainer::RawScriptData>
+ThreadSafeScriptContainer::TakeOnWorkerThread(const KURL& url) {
+ MutexLocker locker(mutex_);
+ auto it = script_data_.find(url);
+ DCHECK(it != script_data_.end())
+ << "Script should have been received before calling Take";
+ std::pair<ScriptStatus, std::unique_ptr<RawScriptData>>& pair = it->value;
+ DCHECK_EQ(ScriptStatus::kReceived, pair.first);
+ pair.first = ScriptStatus::kTaken;
+ return std::move(pair.second);
+}
+
+void ThreadSafeScriptContainer::OnAllDataAddedOnIOThread() {
+ MutexLocker locker(mutex_);
+ are_all_data_added_ = true;
+ waiting_cv_.Broadcast();
+}
+
+ThreadSafeScriptContainer::~ThreadSafeScriptContainer() = default;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h
new file mode 100644
index 00000000000..a495a8ae2f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h
@@ -0,0 +1,138 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
+
+#include <memory>
+#include <utility>
+
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/network/http_header_map.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+// ThreadSafeScriptContainer stores the scripts of a service worker for
+// startup. This container is created for each service worker. The IO thread
+// adds scripts to the container, and the worker thread takes the scripts.
+// Note: Due to the above explanations about multi-threads access on this
+// container, all the non-thread-safe members like KURL and String need to be
+// deep-copied.
+//
+// This class uses explicit synchronization because it needs to support
+// synchronous importScripts() from the worker thread.
+//
+// This class is RefCounted because there is no ordering guarantee of lifetime
+// of its owners, i.e. ServiceWorkerInstalledScriptsManager and its
+// Internal class. ServiceWorkerInstalledScriptsManager is destroyed earlier
+// than Internal if the worker is terminated before all scripts are streamed,
+// and Internal is destroyed earlier if all of scripts are received before
+// finishing script evaluation.
+class MODULES_EXPORT ThreadSafeScriptContainer
+ : public WTF::ThreadSafeRefCounted<ThreadSafeScriptContainer> {
+ public:
+ using BytesChunk = Vector<char>;
+
+ // Container of a script. All the fields of this class need to be
+ // cross-thread-transfer-safe.
+ class MODULES_EXPORT RawScriptData {
+ public:
+ static std::unique_ptr<RawScriptData> Create(const String& encoding,
+ Vector<BytesChunk> script_text,
+ Vector<BytesChunk> meta_data);
+
+ ~RawScriptData();
+
+ void AddHeader(const String& key, const String& value);
+
+ // The encoding of the script text.
+ const String& Encoding() const { return encoding_; }
+ // An array of raw byte chunks of the script text.
+ const Vector<BytesChunk>& ScriptTextChunks() const { return script_text_; }
+ // An array of raw byte chunks of the scripts's meta data from the script's
+ // V8 code cache.
+ const Vector<BytesChunk>& MetaDataChunks() const { return meta_data_; }
+
+ // The HTTP headers of the script.
+ std::unique_ptr<CrossThreadHTTPHeaderMapData> TakeHeaders() {
+ return std::move(headers_);
+ }
+
+ private:
+ RawScriptData(const String& encoding,
+ Vector<BytesChunk> script_text,
+ Vector<BytesChunk> meta_data);
+ String encoding_;
+ Vector<BytesChunk> script_text_;
+ Vector<BytesChunk> meta_data_;
+ std::unique_ptr<CrossThreadHTTPHeaderMapData> headers_;
+ };
+
+ REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
+ ThreadSafeScriptContainer();
+
+ enum class ScriptStatus {
+ // The script data has been received.
+ kReceived,
+ // The script data has been received but it has already been taken.
+ kTaken,
+ // Receiving the script has failed.
+ kFailed,
+ // The script data has not been received yet.
+ kPending
+ };
+
+ // Adds a script for the |url| to the container, and records status of the
+ // script as kReceived when |data| is non-null, or kFailed when |data| is
+ // nullptr. Called on the IO thread.
+ void AddOnIOThread(const KURL& url, std::unique_ptr<RawScriptData> data);
+
+ // Called on the worker thread.
+ ScriptStatus GetStatusOnWorkerThread(const KURL& url);
+
+ // Removes the script. After calling this, ScriptStatus for the
+ // script will be kPending.
+ // Called on the worker thread.
+ void ResetOnWorkerThread(const KURL& url);
+
+ // Waits until the script is added. The thread is blocked until the script is
+ // available or receiving the script fails. Returns false if an error happens
+ // and the waiting script won't be available forever.
+ // Called on the worker thread.
+ bool WaitOnWorkerThread(const KURL& url);
+
+ // Called on the worker thread.
+ std::unique_ptr<RawScriptData> TakeOnWorkerThread(const KURL& url);
+
+ // Called if no more data will be added.
+ // Called on the IO thread.
+ void OnAllDataAddedOnIOThread();
+
+ private:
+ friend class WTF::ThreadSafeRefCounted<ThreadSafeScriptContainer>;
+ ~ThreadSafeScriptContainer();
+
+ // |mutex_| protects |waiting_cv_|, |script_data_|, |waiting_url_| and
+ // |are_all_data_added_|.
+ Mutex mutex_;
+ // |waiting_cv_| is signaled when a script whose url matches to |waiting_url|
+ // is added, or OnAllDataAdded is called. The worker thread waits on this, and
+ // the IO thread signals it.
+ ThreadCondition waiting_cv_;
+ HashMap<KURL, std::pair<ScriptStatus, std::unique_ptr<RawScriptData>>>
+ script_data_;
+ KURL waiting_url_;
+ bool are_all_data_added_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc
new file mode 100644
index 00000000000..b04d2a84135
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc
@@ -0,0 +1,217 @@
+// 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 "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h"
+
+#include <memory>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/waitable_event.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+using ScriptStatus = ThreadSafeScriptContainer::ScriptStatus;
+
+const char kKeyUrl[] = "https://example.com/key";
+
+class ThreadSafeScriptContainerTest : public ::testing::Test {
+ public:
+ ThreadSafeScriptContainerTest()
+ : writer_thread_(Platform::Current()->CreateThread(
+ ThreadCreationParams(WebThreadType::kTestThread)
+ .SetThreadNameForTest("writer_thread"))),
+ reader_thread_(Platform::Current()->CreateThread(
+ ThreadCreationParams(WebThreadType::kTestThread)
+ .SetThreadNameForTest("reader_thread"))),
+ container_(base::MakeRefCounted<ThreadSafeScriptContainer>()) {}
+
+ protected:
+ WaitableEvent* AddOnWriterThread(
+ ThreadSafeScriptContainer::RawScriptData** out_data) {
+ PostCrossThreadTask(
+ *writer_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](scoped_refptr<ThreadSafeScriptContainer> container,
+ ThreadSafeScriptContainer::RawScriptData** out_data,
+ WaitableEvent* waiter) {
+ auto data = ThreadSafeScriptContainer::RawScriptData::Create(
+ String::FromUTF8("utf-8") /* encoding */,
+ Vector<Vector<char>>() /* script_text */,
+ Vector<Vector<char>>() /* meta_data */);
+ *out_data = data.get();
+ container->AddOnIOThread(KURL(kKeyUrl), std::move(data));
+ waiter->Signal();
+ },
+ container_, CrossThreadUnretained(out_data),
+ CrossThreadUnretained(&writer_waiter_)));
+ return &writer_waiter_;
+ }
+
+ WaitableEvent* OnAllDataAddedOnWriterThread() {
+ PostCrossThreadTask(
+ *writer_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](scoped_refptr<ThreadSafeScriptContainer> container,
+ WaitableEvent* waiter) {
+ container->OnAllDataAddedOnIOThread();
+ waiter->Signal();
+ },
+ container_, CrossThreadUnretained(&writer_waiter_)));
+ return &writer_waiter_;
+ }
+
+ WaitableEvent* GetStatusOnReaderThread(ScriptStatus* out_status) {
+ PostCrossThreadTask(
+ *reader_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](scoped_refptr<ThreadSafeScriptContainer> container,
+ ScriptStatus* out_status, WaitableEvent* waiter) {
+ *out_status = container->GetStatusOnWorkerThread(KURL(kKeyUrl));
+ waiter->Signal();
+ },
+ container_, CrossThreadUnretained(out_status),
+ CrossThreadUnretained(&reader_waiter_)));
+ return &reader_waiter_;
+ }
+
+ WaitableEvent* WaitOnReaderThread(bool* out_exists) {
+ PostCrossThreadTask(
+ *reader_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](scoped_refptr<ThreadSafeScriptContainer> container,
+ bool* out_exists, WaitableEvent* waiter) {
+ *out_exists = container->WaitOnWorkerThread(KURL(kKeyUrl));
+ waiter->Signal();
+ },
+ container_, CrossThreadUnretained(out_exists),
+ CrossThreadUnretained(&reader_waiter_)));
+ return &reader_waiter_;
+ }
+
+ WaitableEvent* TakeOnReaderThread(
+ ThreadSafeScriptContainer::RawScriptData** out_data) {
+ PostCrossThreadTask(
+ *reader_thread_->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(
+ [](scoped_refptr<ThreadSafeScriptContainer> container,
+ ThreadSafeScriptContainer::RawScriptData** out_data,
+ WaitableEvent* waiter) {
+ auto data = container->TakeOnWorkerThread(KURL(kKeyUrl));
+ *out_data = data.get();
+ waiter->Signal();
+ },
+ container_, CrossThreadUnretained(out_data),
+ CrossThreadUnretained(&reader_waiter_)));
+ return &reader_waiter_;
+ }
+
+ private:
+ std::unique_ptr<Thread> writer_thread_;
+ std::unique_ptr<Thread> reader_thread_;
+
+ WaitableEvent writer_waiter_;
+ WaitableEvent reader_waiter_;
+
+ scoped_refptr<ThreadSafeScriptContainer> container_;
+};
+
+TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
+ {
+ ScriptStatus result = ScriptStatus::kReceived;
+ GetStatusOnReaderThread(&result)->Wait();
+ EXPECT_EQ(ScriptStatus::kPending, result);
+ }
+
+ ThreadSafeScriptContainer::RawScriptData* added_data;
+ {
+ bool result = false;
+ WaitableEvent* pending_wait = WaitOnReaderThread(&result);
+ // This should not be signaled until data is added.
+ EXPECT_FALSE(pending_wait->IsSignaled());
+ WaitableEvent* pending_write = AddOnWriterThread(&added_data);
+ pending_wait->Wait();
+ pending_write->Wait();
+ EXPECT_TRUE(result);
+ }
+
+ {
+ ScriptStatus result = ScriptStatus::kFailed;
+ GetStatusOnReaderThread(&result)->Wait();
+ EXPECT_EQ(ScriptStatus::kReceived, result);
+ }
+
+ {
+ ThreadSafeScriptContainer::RawScriptData* taken_data;
+ TakeOnReaderThread(&taken_data)->Wait();
+ EXPECT_EQ(added_data, taken_data);
+ }
+
+ {
+ ScriptStatus result = ScriptStatus::kFailed;
+ GetStatusOnReaderThread(&result)->Wait();
+ // The record should exist though it's already taken.
+ EXPECT_EQ(ScriptStatus::kTaken, result);
+ }
+
+ {
+ bool result = false;
+ WaitOnReaderThread(&result)->Wait();
+ // Waiting for the record being already taken should succeed.
+ EXPECT_TRUE(result);
+
+ // The record status should still be |kTaken|.
+ ScriptStatus status = ScriptStatus::kFailed;
+ GetStatusOnReaderThread(&status)->Wait();
+ EXPECT_EQ(ScriptStatus::kTaken, status);
+ }
+
+ // Finish adding data.
+ OnAllDataAddedOnWriterThread()->Wait();
+
+ {
+ bool result = false;
+ WaitOnReaderThread(&result)->Wait();
+ // The record is in |kTaken| status, so Wait shouldn't fail.
+ EXPECT_TRUE(result);
+
+ // The status of record should still be |kTaken|.
+ ScriptStatus status = ScriptStatus::kFailed;
+ GetStatusOnReaderThread(&status)->Wait();
+ EXPECT_EQ(ScriptStatus::kTaken, status);
+ }
+}
+
+TEST_F(ThreadSafeScriptContainerTest, WaitNonExistingKey) {
+ {
+ ScriptStatus result = ScriptStatus::kReceived;
+ GetStatusOnReaderThread(&result)->Wait();
+ EXPECT_EQ(ScriptStatus::kPending, result);
+ }
+
+ {
+ bool result = true;
+ WaitableEvent* pending_wait = WaitOnReaderThread(&result);
+ // This should not be signaled until OnAllDataAdded is called.
+ EXPECT_FALSE(pending_wait->IsSignaled());
+ WaitableEvent* pending_on_all_data_added = OnAllDataAddedOnWriterThread();
+ pending_wait->Wait();
+ pending_on_all_data_added->Wait();
+ // Aborted wait should return false.
+ EXPECT_FALSE(result);
+ }
+
+ {
+ bool result = true;
+ WaitOnReaderThread(&result)->Wait();
+ // Wait fails immediately because OnAllDataAdded is called.
+ EXPECT_FALSE(result);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
index ecbfbbdb272..ceb65d2efd8 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "v8/include/v8.h"
@@ -110,14 +111,16 @@ WaitUntilObserver* WaitUntilObserver::Create(ExecutionContext* context,
}
void WaitUntilObserver::WillDispatchEvent() {
- event_dispatch_time_ = WTF::CurrentTime();
- // When handling a notificationclick or paymentrequest event, we want to
- // allow one window to be focused or opened. These calls are allowed between
- // the call to willDispatchEvent() and the last call to
+ event_dispatch_time_ = WTF::CurrentTimeTicks();
+ // When handling a notificationclick, paymentrequest, or backgroundfetchclick
+ // event, we want to allow one window to be focused or opened. These calls are
+ // allowed between the call to willDispatchEvent() and the last call to
// DecrementPendingPromiseCount(). If waitUntil() isn't called, that means
// between willDispatchEvent() and didDispatchEvent().
- if (type_ == kNotificationClick || type_ == kPaymentRequest)
+ if (type_ == kNotificationClick || type_ == kPaymentRequest ||
+ type_ == kBackgroundFetchClick) {
execution_context_->AllowWindowInteraction();
+ }
DCHECK_EQ(EventDispatchState::kInitial, event_dispatch_state_);
event_dispatch_state_ = EventDispatchState::kDispatching;
@@ -179,11 +182,17 @@ void WaitUntilObserver::WaitUntil(ScriptState* script_state,
}
IncrementPendingPromiseCount();
+
+ // Call Then() separately for fulfilled and rejected cases. This ensures
+ // throwing an exception in |on_promise_fulfilled| doesn't invoke
+ // |on_promise_rejected|.
script_promise.Then(
ThenFunction::CreateFunction(script_state, this, ThenFunction::kFulfilled,
std::move(on_promise_fulfilled)),
- ThenFunction::CreateFunction(script_state, this, ThenFunction::kRejected,
- std::move(on_promise_rejected)));
+ {});
+ script_promise.Then({}, ThenFunction::CreateFunction(
+ script_state, this, ThenFunction::kRejected,
+ std::move(on_promise_rejected)));
}
WaitUntilObserver::WaitUntilObserver(ExecutionContext* context,
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
index 47560c2d683..fa322d6e0c2 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
@@ -110,7 +110,7 @@ class MODULES_EXPORT WaitUntilObserver final
int pending_promises_ = 0;
EventDispatchState event_dispatch_state_ = EventDispatchState::kInitial;
bool has_rejected_promise_ = false;
- double event_dispatch_time_ = 0;
+ TimeTicks event_dispatch_time_;
TaskRunnerTimer<WaitUntilObserver> consume_window_interaction_timer_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index 231bb6286bb..c8dbc3143e4 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.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 "third_party/blink/public/web/web_embedded_worker.h"
+#include "third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h"
#include <memory>
+
#include "testing/gmock/include/gmock/gmock.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/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.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_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
@@ -19,6 +19,8 @@
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
#include "third_party/blink/public/web/web_embedded_worker_start_data.h"
#include "third_party/blink/public/web/web_settings.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
+#include "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -43,61 +45,18 @@ class MockServiceWorkerContextClient : public WebServiceWorkerContextClient {
// message.
proxy->ReadyToEvaluateScript();
}
- void DidEvaluateClassicScript(bool /* success */) override {
+ void DidEvaluateScript(bool /* success */) override {
script_evaluated_event_.Signal();
}
// Work-around for mocking a method that return unique_ptr.
MOCK_METHOD0(CreateServiceWorkerNetworkProviderProxy,
WebServiceWorkerNetworkProvider*());
- MOCK_METHOD0(CreateServiceWorkerProviderProxy, WebServiceWorkerProvider*());
std::unique_ptr<WebServiceWorkerNetworkProvider>
CreateServiceWorkerNetworkProvider() override {
return std::unique_ptr<WebServiceWorkerNetworkProvider>(
CreateServiceWorkerNetworkProviderProxy());
}
- std::unique_ptr<WebServiceWorkerProvider> CreateServiceWorkerProvider()
- override {
- return std::unique_ptr<WebServiceWorkerProvider>(
- CreateServiceWorkerProviderProxy());
- }
- void GetClient(const WebString&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>) override {
- NOTREACHED();
- }
- void GetClients(const WebServiceWorkerClientQueryOptions&,
- std::unique_ptr<WebServiceWorkerClientsCallbacks>) override {
- NOTREACHED();
- }
- void OpenNewTab(const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>) override {
- NOTREACHED();
- }
- void OpenPaymentHandlerWindow(
- const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>) override {
- NOTREACHED();
- }
- void PostMessageToClient(const WebString& uuid,
- TransferableMessage) override {
- NOTREACHED();
- }
- void SkipWaiting(
- std::unique_ptr<WebServiceWorkerSkipWaitingCallbacks>) override {
- NOTREACHED();
- }
- void Claim(std::unique_ptr<WebServiceWorkerClientsClaimCallbacks>) override {
- NOTREACHED();
- }
- void Focus(const WebString& uuid,
- std::unique_ptr<WebServiceWorkerClientCallbacks>) override {
- NOTREACHED();
- }
- void Navigate(const WebString& uuid,
- const WebURL&,
- std::unique_ptr<WebServiceWorkerClientCallbacks>) override {
- NOTREACHED();
- }
void WorkerContextDestroyed() override { termination_event_.Signal(); }
void WaitUntilScriptEvaluated() { script_evaluated_event_.Wait(); }
@@ -109,11 +68,27 @@ class MockServiceWorkerContextClient : public WebServiceWorkerContextClient {
};
class MockServiceWorkerInstalledScriptsManager
- : public WebServiceWorkerInstalledScriptsManager {
+ : public ServiceWorkerInstalledScriptsManager {
public:
- MOCK_CONST_METHOD1(IsScriptInstalled, bool(const WebURL& script_url));
+ MockServiceWorkerInstalledScriptsManager()
+ : ServiceWorkerInstalledScriptsManager(
+ Vector<KURL>() /* installed_urls */,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerRequest(
+ mojo::MessagePipe().handle1),
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHostPtrInfo(
+ mojo::MessagePipe().handle0,
+ mojom::blink::ServiceWorkerInstalledScriptsManagerHost::
+ Version_),
+ // Pass a temporary task runner to ensure
+ // ServiceWorkerInstalledScriptsManager construction succeeds.
+ Platform::Current()
+ ->CreateThread(ThreadCreationParams(WebThreadType::kTestThread)
+ .SetThreadNameForTest("io thread"))
+ ->GetTaskRunner()){};
+ MOCK_CONST_METHOD1(IsScriptInstalled, bool(const KURL& script_url));
MOCK_METHOD1(GetRawScriptData,
- std::unique_ptr<RawScriptData>(const WebURL& script_url));
+ std::unique_ptr<ThreadSafeScriptContainer::RawScriptData>(
+ const KURL& script_url));
};
class WebEmbeddedWorkerImplTest : public testing::Test {
@@ -124,10 +99,8 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
std::make_unique<MockServiceWorkerInstalledScriptsManager>();
mock_client_ = client.get();
mock_installed_scripts_manager_ = installed_scripts_manager.get();
- worker_ = WebEmbeddedWorker::Create(
- std::move(client), std::move(installed_scripts_manager),
- mojo::ScopedMessagePipeHandle(), mojo::ScopedMessagePipeHandle(),
- mojo::ScopedMessagePipeHandle());
+ worker_ = WebEmbeddedWorkerImpl::CreateForTesting(
+ std::move(client), std::move(installed_scripts_manager));
WebURL script_url = URLTestHelpers::ToKURL("https://www.example.com/sw.js");
WebURLResponse response(script_url);
@@ -138,6 +111,7 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
start_data_.script_url = script_url;
start_data_.user_agent = WebString("dummy user agent");
+ start_data_.script_type = mojom::ScriptType::kClassic;
start_data_.pause_after_download_mode =
WebEmbeddedWorkerStartData::kDontPauseAfterDownload;
start_data_.wait_for_debugger_mode =
@@ -154,7 +128,7 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
WebEmbeddedWorkerStartData start_data_;
MockServiceWorkerContextClient* mock_client_;
MockServiceWorkerInstalledScriptsManager* mock_installed_scripts_manager_;
- std::unique_ptr<WebEmbeddedWorker> worker_;
+ std::unique_ptr<WebEmbeddedWorkerImpl> worker_;
};
} // namespace
@@ -190,7 +164,7 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileLoadingScript) {
EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy())
.WillOnce(testing::Return(nullptr));
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
@@ -214,7 +188,7 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhilePausedAfterDownload) {
EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy())
.WillOnce(testing::Return(nullptr));
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
@@ -224,12 +198,10 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhilePausedAfterDownload) {
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoaded()).Times(1);
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy()).Times(0);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
testing::Mock::VerifyAndClearExpectations(mock_client_);
// Terminate before resuming after download.
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy()).Times(0);
EXPECT_CALL(*mock_client_, WorkerContextFailedToStart()).Times(1);
worker_->TerminateWorkerContext();
testing::Mock::VerifyAndClearExpectations(mock_client_);
@@ -254,7 +226,7 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy())
.WillOnce(testing::Return(nullptr));
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
@@ -264,7 +236,6 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoaded()).Times(0);
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy()).Times(0);
EXPECT_CALL(*mock_client_, WorkerContextFailedToStart()).Times(1);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
testing::Mock::VerifyAndClearExpectations(mock_client_);
@@ -286,7 +257,7 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy())
.WillOnce(testing::Return(nullptr));
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
@@ -295,11 +266,9 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoaded()).Times(1);
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy())
- .WillOnce(testing::Return(nullptr));
// This is called on the worker thread.
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
@@ -331,7 +300,7 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_PauseAfterDownload) {
EXPECT_CALL(*mock_client_, CreateServiceWorkerNetworkProviderProxy())
.WillOnce(testing::Return(nullptr));
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
@@ -340,16 +309,13 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_PauseAfterDownload) {
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoaded()).Times(1);
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy()).Times(0);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
testing::Mock::VerifyAndClearExpectations(mock_client_);
// Resume after download.
- EXPECT_CALL(*mock_client_, CreateServiceWorkerProviderProxy())
- .WillOnce(testing::Return(nullptr));
// This is called on the worker thread.
EXPECT_CALL(*mock_installed_scripts_manager_,
- IsScriptInstalled(start_data_.script_url))
+ IsScriptInstalled(KURL(start_data_.script_url)))
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
worker_->ResumeAfterDownload();
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
index 402e2f647cc..09cafa69fe5 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/shapedetection/detected_barcode.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
namespace blink {
@@ -39,6 +40,21 @@ DetectedBarcode::DetectedBarcode(String raw_value,
bounding_box_(bounding_box),
corner_points_(corner_points) {}
+ScriptValue DetectedBarcode::toJSONForBinding(ScriptState* script_state) const {
+ V8ObjectBuilder result(script_state);
+ result.AddString("rawValue", rawValue());
+ result.Add("boundingBox", boundingBox()->toJSONForBinding(script_state));
+ Vector<ScriptValue> corner_points;
+ for (const auto& corner_point : corner_points_) {
+ V8ObjectBuilder builder(script_state);
+ builder.AddNumber("x", corner_point.x());
+ builder.AddNumber("y", corner_point.y());
+ corner_points.push_back(builder.GetScriptValue());
+ }
+ result.Add("cornerPoints", corner_points);
+ return result.GetScriptValue();
+}
+
void DetectedBarcode::Trace(blink::Visitor* visitor) {
visitor->Trace(bounding_box_);
visitor->Trace(corner_points_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
index 69dcfd9ddde..c6f2fe11c65 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -24,6 +25,8 @@ class MODULES_EXPORT DetectedBarcode final : public ScriptWrappable {
const String& rawValue() const;
DOMRectReadOnly* boundingBox() const;
const HeapVector<Point2D>& cornerPoints() const;
+
+ ScriptValue toJSONForBinding(ScriptState*) const;
void Trace(blink::Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
index 8d6aa759712..7df4129c703 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
@@ -6,6 +6,7 @@
[
Constructor,
+ Serializable,
OriginTrialEnabled=ShapeDetection
] interface DetectedBarcode {
// TODO(mcasas): Implement missing fields. https://crbug.com/646083
@@ -14,4 +15,6 @@
// 4 corner points in clockwise direction starting with top-left. Due to
// possible perspective distortions, this is not necessarily a rectangle.
[SameObject, SaveSameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
+
+ serializer = { attribute };
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc
index 00863ffbbb7..8228b01bf5a 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/shapedetection/detected_face.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
namespace blink {
@@ -36,6 +37,27 @@ DetectedFace::DetectedFace(DOMRectReadOnly* bounding_box,
const HeapVector<Landmark>& landmarks)
: bounding_box_(bounding_box), landmarks_(landmarks) {}
+ScriptValue DetectedFace::toJSONForBinding(ScriptState* script_state) const {
+ V8ObjectBuilder result(script_state);
+ result.Add("boundingBox", boundingBox()->toJSONForBinding(script_state));
+ Vector<ScriptValue> landmarks;
+ for (const auto& landmark : landmarks_) {
+ V8ObjectBuilder landmark_builder(script_state);
+ landmark_builder.AddString("type", landmark.type());
+ Vector<ScriptValue> locations;
+ for (const auto& location : landmark.locations()) {
+ V8ObjectBuilder location_builder(script_state);
+ location_builder.AddNumber("x", location.x());
+ location_builder.AddNumber("y", location.y());
+ locations.push_back(location_builder.GetScriptValue());
+ }
+ landmark_builder.Add("locations", locations);
+ landmarks.push_back(landmark_builder.GetScriptValue());
+ }
+ result.Add("landmarks", landmarks);
+ return result.GetScriptValue();
+}
+
void DetectedFace::Trace(blink::Visitor* visitor) {
visitor->Trace(bounding_box_);
visitor->Trace(landmarks_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h
index 0e5268aa2de..6935e84330d 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_FACE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_FACE_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -24,6 +25,7 @@ class MODULES_EXPORT DetectedFace final : public ScriptWrappable {
DOMRectReadOnly* boundingBox() const;
const HeapVector<Landmark>& landmarks() const;
+ ScriptValue toJSONForBinding(ScriptState*) const;
void Trace(blink::Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
index fda03e7c2f0..f367b6af6b9 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
@@ -6,9 +6,12 @@
[
Constructor,
+ Serializable,
OriginTrialEnabled=ShapeDetection
] interface DetectedFace {
// TODO(xianglu): Implement any other fields. https://crbug.com/646083
[SameObject] readonly attribute DOMRectReadOnly boundingBox;
[SameObject, SaveSameObject] readonly attribute FrozenArray<Landmark> landmarks;
+
+ serializer = { attribute };
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc
index 7240b5c502c..7a03de27916 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/shapedetection/detected_text.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
namespace blink {
@@ -39,6 +40,21 @@ DetectedText::DetectedText(String raw_value,
bounding_box_(bounding_box),
corner_points_(corner_points) {}
+ScriptValue DetectedText::toJSONForBinding(ScriptState* script_state) const {
+ V8ObjectBuilder result(script_state);
+ result.AddString("rawValue", rawValue());
+ result.Add("boundingBox", boundingBox()->toJSONForBinding(script_state));
+ Vector<ScriptValue> corner_points;
+ for (const auto& corner_point : corner_points_) {
+ V8ObjectBuilder builder(script_state);
+ builder.AddNumber("x", corner_point.x());
+ builder.AddNumber("y", corner_point.y());
+ corner_points.push_back(builder.GetScriptValue());
+ }
+ result.Add("cornerPoints", corner_points);
+ return result.GetScriptValue();
+}
+
void DetectedText::Trace(blink::Visitor* visitor) {
visitor->Trace(bounding_box_);
visitor->Trace(corner_points_);
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h
index 342072d3e57..09f43783bc6 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_TEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_TEXT_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -24,6 +25,8 @@ class MODULES_EXPORT DetectedText final : public ScriptWrappable {
const String& rawValue() const;
DOMRectReadOnly* boundingBox() const;
const HeapVector<Point2D>& cornerPoints() const;
+
+ ScriptValue toJSONForBinding(ScriptState*) const;
void Trace(blink::Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
index 8b08cde053c..7afa4c66f2b 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
@@ -6,6 +6,7 @@
[
Constructor,
+ Serializable,
OriginTrialEnabled=ShapeDetection
] interface DetectedText {
[SameObject] readonly attribute DOMString rawValue;
@@ -13,4 +14,6 @@
// 4 corner points in clockwise direction starting with top-left. Due to
// possible perspective distortions, this is not necessarily a rectangle.
[SameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
+
+ serializer = { attribute };
};
diff --git a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
index df1bbde0c12..5597ba5fa8e 100644
--- a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn
@@ -30,6 +30,8 @@ blink_modules_sources("speech") {
"speech_recognition_result_list.h",
"speech_synthesis.cc",
"speech_synthesis.h",
+ "speech_synthesis_error_event.cc",
+ "speech_synthesis_error_event.h",
"speech_synthesis_event.cc",
"speech_synthesis_event.h",
"speech_synthesis_utterance.cc",
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
index 0e60f9ac463..59982229e20 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
@@ -39,7 +39,7 @@ SpeechGrammar* SpeechGrammar::Create(const KURL& src, double weight) {
}
void SpeechGrammar::setSrc(ScriptState* script_state, const String& src) {
- Document* document = ToDocument(ExecutionContext::From(script_state));
+ Document* document = To<Document>(ExecutionContext::From(script_state));
src_ = document->CompleteURL(src);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
index 531a0a42f38..2c7ce846f9c 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc
@@ -45,7 +45,7 @@ SpeechGrammar* SpeechGrammarList::item(unsigned index) const {
void SpeechGrammarList::addFromUri(ScriptState* script_state,
const String& src,
double weight) {
- Document* document = ToDocument(ExecutionContext::From(script_state));
+ Document* document = To<Document>(ExecutionContext::From(script_state));
grammars_.push_back(
SpeechGrammar::Create(document->CompleteURL(src), weight));
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
index 9f2d5589ba9..5047cac243d 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -37,11 +37,8 @@
namespace blink {
SpeechRecognition* SpeechRecognition::Create(ExecutionContext* context) {
- DCHECK(context);
- DCHECK(context->IsDocument());
- Document* document = ToDocument(context);
- DCHECK(document);
- return new SpeechRecognition(document->GetFrame(), context);
+ Document& document = To<Document>(*context);
+ return new SpeechRecognition(document.GetFrame(), context);
}
void SpeechRecognition::start(ExceptionState& exception_state) {
@@ -96,7 +93,7 @@ void SpeechRecognition::ResultRetrieved(
auto* it = std::stable_partition(
results.begin(), results.end(),
[](const auto& result) { return !result->is_provisional; });
- size_t provisional_count = results.end() - it;
+ wtf_size_t provisional_count = static_cast<wtf_size_t>(results.end() - it);
// Add the new results to the previous final results.
HeapVector<Member<SpeechRecognitionResult>> aggregated_results =
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
index b4e08c6ccf8..ed6259ee8d8 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
@@ -129,7 +129,7 @@ class MODULES_EXPORT SpeechRecognition final
String lang_;
bool continuous_;
bool interim_results_;
- unsigned long max_alternatives_;
+ uint32_t max_alternatives_;
Member<SpeechRecognitionController> controller_;
bool started_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
index 6bd603d0da6..c16ed4933c7 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc
@@ -56,7 +56,7 @@ void SpeechRecognitionController::Start(
const String& lang,
bool continuous,
bool interim_results,
- unsigned long max_alternatives) {
+ uint32_t max_alternatives) {
mojom::blink::StartSpeechRecognitionRequestParamsPtr msg_params =
mojom::blink::StartSpeechRecognitionRequestParams::New();
for (unsigned i = 0; i < grammars.length(); i++) {
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
index 1f98f355d1f..06c4c2a9080 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
@@ -52,7 +52,7 @@ class SpeechRecognitionController final
const String& lang,
bool continuous,
bool interim_results,
- unsigned long max_alternatives);
+ uint32_t max_alternatives);
static SpeechRecognitionController* Create(LocalFrame& frame);
static SpeechRecognitionController* From(LocalFrame* frame) {
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
index 8c77fcda614..5236cc5eaa4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc
@@ -36,7 +36,7 @@ SpeechRecognitionEvent* SpeechRecognitionEvent::Create(
}
SpeechRecognitionEvent* SpeechRecognitionEvent::CreateResult(
- unsigned long result_index,
+ uint32_t result_index,
const HeapVector<Member<SpeechRecognitionResult>>& results) {
return new SpeechRecognitionEvent(
EventTypeNames::result, result_index,
@@ -72,7 +72,7 @@ SpeechRecognitionEvent::SpeechRecognitionEvent(
SpeechRecognitionEvent::SpeechRecognitionEvent(
const AtomicString& event_name,
- unsigned long result_index,
+ uint32_t result_index,
SpeechRecognitionResultList* results)
: Event(event_name, Bubbles::kNo, Cancelable::kNo),
result_index_(result_index),
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
index 7348f0489e9..5bf5b563ec4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h
@@ -45,11 +45,11 @@ class SpeechRecognitionEvent final : public Event {
~SpeechRecognitionEvent() override;
static SpeechRecognitionEvent* CreateResult(
- unsigned long result_index,
+ uint32_t result_index,
const HeapVector<Member<SpeechRecognitionResult>>& results);
static SpeechRecognitionEvent* CreateNoMatch(SpeechRecognitionResult*);
- unsigned long resultIndex() const { return result_index_; }
+ uint32_t resultIndex() const { return result_index_; }
SpeechRecognitionResultList* results() const { return results_; }
// These two methods are here to satisfy the specification which requires
@@ -66,10 +66,10 @@ class SpeechRecognitionEvent final : public Event {
SpeechRecognitionEvent(const AtomicString&,
const SpeechRecognitionEventInit&);
SpeechRecognitionEvent(const AtomicString& event_name,
- unsigned long result_index,
+ uint32_t result_index,
SpeechRecognitionResultList* results);
- unsigned long result_index_;
+ uint32_t result_index_;
Member<SpeechRecognitionResultList> results_;
};
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
index b873d8ed6b9..c86e56d786b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -32,7 +32,10 @@
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_event.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_event_init.h"
#include "third_party/blink/renderer/platform/speech/platform_speech_synthesis_voice.h"
namespace blink {
@@ -67,9 +70,8 @@ const HeapVector<Member<SpeechSynthesisVoice>>& SpeechSynthesis::getVoices() {
// platform again.
const Vector<scoped_refptr<PlatformSpeechSynthesisVoice>>& platform_voices =
platform_speech_synthesizer_->GetVoiceList();
- size_t voice_count = platform_voices.size();
- for (size_t k = 0; k < voice_count; k++)
- voice_list_.push_back(SpeechSynthesisVoice::Create(platform_voices[k]));
+ for (auto voice : platform_voices)
+ voice_list_.push_back(SpeechSynthesisVoice::Create(voice));
return voice_list_;
}
@@ -106,14 +108,10 @@ void SpeechSynthesis::StartSpeakingImmediately() {
void SpeechSynthesis::speak(SpeechSynthesisUtterance* utterance) {
DCHECK(utterance);
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
if (!document)
return;
- // If SpeechSynthesis followed autoplay policy, we could simply fire an error
- // here and ignore this utterance. For now, just log some UseCounters to
- // evaluate potential breakage.
- //
// Note: Non-UseCounter based TTS metrics are of the form TextToSpeech.* and
// are generally global, whereas these are scoped to a single page load.
UseCounter::Count(document, WebFeature::kTextToSpeech_Speak);
@@ -122,6 +120,8 @@ void SpeechSynthesis::speak(SpeechSynthesisUtterance* utterance) {
if (!IsAllowedToStartByAutoplay()) {
Deprecation::CountDeprecation(
document, WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay);
+ FireErrorEvent(utterance, 0 /* char_index */, "not-allowed");
+ return;
}
utterance_queue_.push_back(utterance);
@@ -152,15 +152,34 @@ void SpeechSynthesis::resume() {
void SpeechSynthesis::FireEvent(const AtomicString& type,
SpeechSynthesisUtterance* utterance,
- unsigned long char_index,
+ uint32_t char_index,
const String& name) {
double millis;
if (!GetElapsedTimeMillis(&millis))
return;
- double elapsed_time_millis = millis - utterance->StartTime() * 1000.0;
- utterance->DispatchEvent(*SpeechSynthesisEvent::Create(
- type, utterance, char_index, elapsed_time_millis, name));
+ SpeechSynthesisEventInit init;
+ init.setUtterance(utterance);
+ init.setCharIndex(char_index);
+ init.setElapsedTime(millis - (utterance->StartTime() * 1000.0));
+ init.setName(name);
+ utterance->DispatchEvent(*SpeechSynthesisEvent::Create(type, init));
+}
+
+void SpeechSynthesis::FireErrorEvent(SpeechSynthesisUtterance* utterance,
+ unsigned long char_index,
+ const String& error) {
+ double millis;
+ if (!GetElapsedTimeMillis(&millis))
+ return;
+
+ SpeechSynthesisErrorEventInit init;
+ init.setUtterance(utterance);
+ init.setCharIndex(char_index);
+ init.setElapsedTime(millis - (utterance->StartTime() * 1000.0));
+ init.setError(error);
+ utterance->DispatchEvent(
+ *SpeechSynthesisErrorEvent::Create(EventTypeNames::error, init));
}
void SpeechSynthesis::HandleSpeakingCompleted(
@@ -180,8 +199,13 @@ void SpeechSynthesis::HandleSpeakingCompleted(
// sent an event on an utterance before it got the message that we
// canceled it, and we should always report to the user what actually
// happened.
- FireEvent(error_occurred ? EventTypeNames::error : EventTypeNames::end,
- utterance, 0, String());
+ if (error_occurred) {
+ // TODO(csharrison): Actually pass the correct message. For now just use a
+ // generic error.
+ FireErrorEvent(utterance, 0, "synthesis-failed");
+ } else {
+ FireEvent(EventTypeNames::end, utterance, 0, String());
+ }
// Start the next utterance if we just finished one and one was pending.
if (should_start_speaking && !utterance_queue_.IsEmpty())
@@ -274,7 +298,7 @@ void SpeechSynthesis::Trace(blink::Visitor* visitor) {
bool SpeechSynthesis::GetElapsedTimeMillis(double* millis) {
if (!GetExecutionContext())
return false;
- Document* delegate_document = ToDocument(GetExecutionContext());
+ Document* delegate_document = To<Document>(GetExecutionContext());
if (!delegate_document || delegate_document->IsStopped())
return false;
LocalDOMWindow* delegate_dom_window = delegate_document->domWindow();
@@ -286,7 +310,7 @@ bool SpeechSynthesis::GetElapsedTimeMillis(double* millis) {
}
bool SpeechSynthesis::IsAllowedToStartByAutoplay() const {
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
DCHECK(document);
// Note: could check the utterance->volume here, but that could be overriden
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
index 4b87c237429..850407dad5a 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -89,9 +89,13 @@ class MODULES_EXPORT SpeechSynthesis final
void HandleSpeakingCompleted(SpeechSynthesisUtterance*, bool error_occurred);
void FireEvent(const AtomicString& type,
SpeechSynthesisUtterance*,
- unsigned long char_index,
+ uint32_t char_index,
const String& name);
+ void FireErrorEvent(SpeechSynthesisUtterance*,
+ unsigned long char_index,
+ const String& error);
+
// Returns the utterance at the front of the queue.
SpeechSynthesisUtterance* CurrentSpeechUtterance() const;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.cc
new file mode 100644
index 00000000000..40801425425
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h"
+
+namespace blink {
+
+// static
+SpeechSynthesisErrorEvent* SpeechSynthesisErrorEvent::Create(
+ const AtomicString& type,
+ const SpeechSynthesisErrorEventInit& init) {
+ return new SpeechSynthesisErrorEvent(type, init);
+}
+
+SpeechSynthesisErrorEvent::SpeechSynthesisErrorEvent(
+ const AtomicString& type,
+ const SpeechSynthesisErrorEventInit& init)
+ : SpeechSynthesisEvent(type,
+ init.utterance(),
+ init.charIndex(),
+ init.elapsedTime(),
+ init.name()),
+ error_(init.error()) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h
new file mode 100644
index 00000000000..24be96080e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_ERROR_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_ERROR_EVENT_H_
+
+#include "third_party/blink/renderer/modules/event_modules.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_event.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class SpeechSynthesisErrorEvent : public SpeechSynthesisEvent {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static SpeechSynthesisErrorEvent* Create(
+ const AtomicString& type,
+ const SpeechSynthesisErrorEventInit& init);
+
+ const String error() const { return error_; }
+
+ private:
+ SpeechSynthesisErrorEvent(const AtomicString& type,
+ const SpeechSynthesisErrorEventInit& init);
+ const String error_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_ERROR_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl
new file mode 100644
index 00000000000..ec5d7809207
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl
@@ -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.
+
+// https://w3c.github.io/speech-api/#enumdef-speechsynthesiserrorcode
+enum SpeechSynthesisErrorCode {
+ "canceled",
+ "interrupted",
+ "audio-busy",
+ "audio-hardware",
+ "network",
+ "synthesis-unavailable",
+ "synthesis-failed",
+ "language-unavailable",
+ "voice-unavailable",
+ "text-too-long",
+ "invalid-argument",
+ "not-allowed",
+};
+
+// https://w3c.github.io/speech-api/#speechsynthesiserrorevent
+[
+ Exposed=Window,
+ Constructor(DOMString type, SpeechSynthesisErrorEventInit eventInitDict),
+ RuntimeEnabled=ScriptedSpeech
+] interface SpeechSynthesisErrorEvent : SpeechSynthesisEvent {
+ readonly attribute SpeechSynthesisErrorCode error;
+};
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl
new file mode 100644
index 00000000000..d6d201e6f99
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl
@@ -0,0 +1,8 @@
+// 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.
+
+// https://w3c.github.io/speech-api/#dictdef-speechsynthesiseventinit
+dictionary SpeechSynthesisErrorEventInit : SpeechSynthesisEventInit {
+ required SpeechSynthesisErrorCode error;
+};
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
index d8e51cd8f56..6e0ab68cdbc 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc
@@ -27,22 +27,13 @@
namespace blink {
-SpeechSynthesisEvent* SpeechSynthesisEvent::Create() {
- return new SpeechSynthesisEvent;
-}
-
SpeechSynthesisEvent* SpeechSynthesisEvent::Create(
const AtomicString& type,
- SpeechSynthesisUtterance* utterance,
- unsigned char_index,
- float elapsed_time,
- const String& name) {
- return new SpeechSynthesisEvent(type, utterance, char_index, elapsed_time,
- name);
+ const SpeechSynthesisEventInit& init) {
+ return new SpeechSynthesisEvent(type, init.utterance(), init.charIndex(),
+ init.elapsedTime(), init.name());
}
-SpeechSynthesisEvent::SpeechSynthesisEvent() = default;
-
SpeechSynthesisEvent::SpeechSynthesisEvent(const AtomicString& type,
SpeechSynthesisUtterance* utterance,
unsigned char_index,
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
index 2a55b6f8528..71fbf3e31e4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h
@@ -27,20 +27,17 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_EVENT_H_
#include "third_party/blink/renderer/modules/event_modules.h"
+#include "third_party/blink/renderer/modules/speech/speech_synthesis_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h"
namespace blink {
-class SpeechSynthesisEvent final : public Event {
+class SpeechSynthesisEvent : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
- static SpeechSynthesisEvent* Create();
static SpeechSynthesisEvent* Create(const AtomicString& type,
- SpeechSynthesisUtterance*,
- unsigned char_index,
- float elapsed_time,
- const String& name);
+ const SpeechSynthesisEventInit& init);
SpeechSynthesisUtterance* utterance() const { return utterance_; }
unsigned charIndex() const { return char_index_; }
@@ -53,14 +50,14 @@ class SpeechSynthesisEvent final : public Event {
void Trace(blink::Visitor*) override;
- private:
- SpeechSynthesisEvent();
+ protected:
SpeechSynthesisEvent(const AtomicString& type,
SpeechSynthesisUtterance*,
unsigned char_index,
float elapsed_time,
const String& name);
+ private:
Member<SpeechSynthesisUtterance> utterance_;
unsigned char_index_;
float elapsed_time_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
index 4c35b5d5b25..0f9e01be747 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
@@ -23,10 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://dvcs.w3.org/hg/speech-api/raw-file/tip/webspeechapi.html#tts-section
-
+// https://w3c.github.io/speech-api/#speechsynthesisevent
[
- RuntimeEnabled=ScriptedSpeech
+ RuntimeEnabled=ScriptedSpeech,
+ Constructor(DOMString type, SpeechSynthesisEventInit eventInitDict)
] interface SpeechSynthesisEvent : Event {
readonly attribute SpeechSynthesisUtterance utterance;
readonly attribute unsigned long charIndex;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl
new file mode 100644
index 00000000000..0c1386f94be
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// https://w3c.github.io/speech-api/#dictdef-speechsynthesiseventinit
+dictionary SpeechSynthesisEventInit : EventInit {
+ required SpeechSynthesisUtterance utterance;
+ unsigned long charIndex = 0;
+ float elapsedTime = 0;
+ DOMString name = "";
+};
diff --git a/chromium/third_party/blink/renderer/modules/storage/BUILD.gn b/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
index 4a5dba165ea..b76fee95b96 100644
--- a/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
@@ -18,12 +18,12 @@ blink_modules_sources("storage") {
"storage_area.h",
"storage_area_map.cc",
"storage_area_map.h",
+ "storage_controller.cc",
+ "storage_controller.h",
"storage_event.cc",
"storage_event.h",
"storage_namespace.cc",
"storage_namespace.h",
- "storage_namespace_controller.cc",
- "storage_namespace_controller.h",
]
}
@@ -32,6 +32,8 @@ jumbo_source_set("unit_tests") {
sources = [
"cached_storage_area_test.cc",
"storage_area_map_test.cc",
+ "storage_controller_test.cc",
+ "storage_namespace_test.cc",
"testing/fake_area_source.h",
"testing/mock_storage_area.cc",
"testing/mock_storage_area.h",
diff --git a/chromium/third_party/blink/renderer/modules/storage/README.md b/chromium/third_party/blink/renderer/modules/storage/README.md
index 1b1875d7e38..68e29ac989c 100644
--- a/chromium/third_party/blink/renderer/modules/storage/README.md
+++ b/chromium/third_party/blink/renderer/modules/storage/README.md
@@ -1,25 +1,101 @@
# `blink/renderer/modules/storage`
-This diretory contains the renderer side implementation of the DOM Storage API.
-This API is defined in the
-[HTML Spec](https://html.spec.whatwg.org/multipage/webstorage.html)'s section on
-Web Storage.
+This directory contains the renderer side implementation of the DOM Storage API. This API is defined in the [HTML Spec](https://html.spec.whatwg.org/multipage/webstorage.html)'s section on Web Storage.
The browser side code for this lives in `content/browser/dom_storage/`.
-## Class structure
+*TODO(dmurph): Delete this paragraph after onion-souping is complete.
+https://crbug.com/781870*
+This file describes only the post-onion-souped version of the code, where
+`features::kOnionSoupDOMStorage` is turned on. This is not yet the default.
-`StorageArea` implements the WebIDL `Storage` interface. Instances of this class
-will in the future hold a reference to a shared `CachedStorageArea` instance.
-All `StorageArea` instances representing the same area will use the same
-`CachedStorageArea` instance. Today instead each `StorageArea` owns a separate
-`WebStorageArea` instance, implemented by the content layer.
+## Class Responsibilities
+### [`DOMWindowStorage`](dom_storage_window.h)
+This implements the partial `Window` interface in
+[window_storage.idl](window_storage.idl), and provides bindings for
+`window.localStorage` and `window.sessionStorage` to the web platform. This
+creates & owns the `StorageArea` objects.
+### [`StorageArea`](storage_area.h)
+This implements the WebIDL `Storage` interface in [storage.idl](storage.idl),
+and provides access to `localStorage` and `sessionStorage`. This class holds a
+shared reference to a `CachedStorageArea` (which can be shared between multiple
+`StorageArea`s), and basically delegates most calls here.
-`CachedStorageArea` will be responsible for communicating with the browser
-process over the `StorageArea` mojom interface. It will also cache all the data
-for a area in a `StorageAreaMap` instance, and will dispatch events it receives
-to the relevant `StorageArea` and `InspectorDOMStorageAgent` instances.
+This is also temporarily created & used by `InspectorDOMStorageAgent` to make modifications to local & session storage.
+### [`CachedStorageArea`](cached_storage_area.h)
+This is responsible for
+ * keeping a local cache of the localStorage or sessionStorage data (which it
+ does using a [`StorageAreaMap`](storage_area_map.h)),
+ * keeping track of `Source`s that are using this cached storage area (which
+ are `StorageAreas`),
+ * loading and saving data with a
+ [`StorageArea`](../../../public/mojom/dom_storage/storage_area.mojom) mojo
+ interface, and
+ * observing changes from that `StorageArea` interface and communicating these
+ to all `Source`s, and `InspectorEventListener`s.
+### [`StorageAreaMap`](storage_area_map.h)
+This represents an in-memory cache of a storage area. It holds key-value
+storage and keeps track of the total size of the bytes stored.
+### [`StorageNamespace`](storage_namespace.h)
+This class is responsible for
+ * creating & caching `CachedStorageArea`s on a per-origin basis,
+ * holding weak references to `DOMStorageInspectorAgent`s & telling them when a
+ storage event was dispatched,
+ * interacting with the
+ [`StoragePartitionService`](../../../public/mojom/dom_storage/storage_partition_service.mojom)
+ and
+ [`SessionStorageNamespace`](../../../public/mojom/dom_storage/session_storage_namespace.mojom)
+ mojo interfaces to create `StorageArea` mojo ptrs for the `CachedStorageArea`s
+ and clone namespaces for SessionStorage.
+* accounting for all storage used in it's cached areas, and
+* cleaning up unused caches areas on demand.
-`StorageAreaMap` represents the in-memory version of the data in a particular
-storage area. It will be owned by a instance of the (yet-to-be-written)
-`CachedStorageArea` class.
+There are two versions of this class - one version is the SessionStorage
+version, which holds a
+[`SessionStorageNamespace`](../../../public/mojom/dom_storage/session_storage_namespace.mojom)
+mojo ptr and lives on a `Page` as a Page Supplement. The other version is for
+LocalStorage, which just uses the
+[`StoragePartitionService`](../../../public/mojom/dom_storage/storage_partition_service.mojom)
+to open the `StorageAreas`, and is owned by the `StorageController`.
+
+### [`StorageController`](storage_controller.h)
+This is a singleton that is responsible for keeping track of all
+`StorageNamespace`s and provide access to the functionality of it's single
+LocalStorage `StorageNamespace` that it owns. It holds weak references to all
+of the SessionStorage `StorageNamespace`s so it can account for the total
+amount of memory used by all of DOMStorage. If this gets too high, it can ask
+all namespaces to prune all unused `CacheStorageArea`s.
+### [`InspectorDOMStorageAgent`](inspector_dom_storage_agent.h)
+This is used by the Inspector (DevTools) code to listen to and modify local &
+session storage. The `StorageNamespace` class allows these agents to be added &
+removed by the Inspector system, and all events that are dispatched on that
+namespace are sent to its `InspectorDOMStorageAgent`s.
+
+This class also creates a temporary `StorageArea` to query & modify local &
+session storage.
+## Class Ownership Structure
+`StorageArea` lives on the `window`. Instances of this class hold a reference
+to a `CachedStorageArea` instance. All `StorageArea` instances representing the
+same area use the same `CachedStorageArea` instance (which is reference
+counted). Two classes are used to create and manage `CachedStorageArea`s - the
+`StorageController`, and `StorageNamespace`s.
+
+The `StorageNamespace` represents a SessionStorage namespace, but can also be
+used for LocalStorage. It creates & manages `CachedStorageArea`s per-origin. It
+keeps a reference to all `CachedStorageArea`s it creates for memory accounting
+and object re-use. It also contains weak references to
+`InspectorDOMStorageAgent`s that it notifies when StorageEvents are dispatched.
+
+SessionStorage `StorageNamespace` objects live as supplements on the `Page`, so
+each `Page` owns one. The LocalStorage `StorageNamespace` object lives in the
+`StorageController`.
+
+The `StorageController` is a singleton. It owns the LocalStorage
+`StorageNamespace`, and hold weak references to each SessionStorage
+`StorageNamespace`.
+
+Finally - `InspectorDomStorageAgent` will create temporary `StorageArea`
+objects when it wants to query or modify DOMStorage.
+
+![Object ownership graph](docs/ownership.png)
+[Image Source](https://docs.google.com/drawings/d/1YlaLMyJT5G8jqU_wHnldWIA3LEtGBPFs39gLkikAzyc/edit?usp=sharing)
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
index 0cf518029b5..afc5524c536 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
@@ -64,18 +64,20 @@ void UnpackSource(const String& source,
scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForLocalStorage(
scoped_refptr<const SecurityOrigin> origin,
mojo::InterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner) {
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener) {
return base::AdoptRef(new CachedStorageArea(
- std::move(origin), std::move(area), std::move(ipc_runner)));
+ std::move(origin), std::move(area), std::move(ipc_runner), listener));
}
// static
scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForSessionStorage(
scoped_refptr<const SecurityOrigin> origin,
mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner) {
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener) {
return base::AdoptRef(new CachedStorageArea(
- std::move(origin), std::move(area), std::move(ipc_runner)));
+ std::move(origin), std::move(area), std::move(ipc_runner), listener));
}
unsigned CachedStorageArea::GetLength() {
@@ -96,7 +98,7 @@ String CachedStorageArea::GetItem(const String& key) {
bool CachedStorageArea::SetItem(const String& key,
const String& value,
Source* source) {
- DCHECK(areas_.Contains(source));
+ DCHECK(areas_->Contains(source));
// A quick check to reject obviously overbudget items to avoid priming the
// cache.
@@ -123,7 +125,7 @@ bool CachedStorageArea::SetItem(const String& key,
optional_old_value = StringToUint8Vector(old_value, value_format);
KURL page_url = source->GetPageUrl();
- String source_id = areas_.at(source);
+ String source_id = areas_->at(source);
blink::WebScopedVirtualTimePauser virtual_time_pauser =
source->CreateWebScopedVirtualTimePauser(
@@ -136,17 +138,13 @@ bool CachedStorageArea::SetItem(const String& key,
WTF::Bind(&CachedStorageArea::OnSetItemComplete,
weak_factory_.GetWeakPtr(), key,
std::move(virtual_time_pauser)));
- if (IsSessionStorage() && old_value != value) {
- for (const auto& area : areas_) {
- if (area.key != source)
- area.key->EnqueueStorageEvent(key, old_value, value, page_url);
- }
- }
+ if (IsSessionStorage() && old_value != value)
+ EnqueueStorageEvent(key, old_value, value, page_url, source_id);
return true;
}
void CachedStorageArea::RemoveItem(const String& key, Source* source) {
- DCHECK(areas_.Contains(source));
+ DCHECK(areas_->Contains(source));
EnsureLoaded();
String old_value;
@@ -167,7 +165,7 @@ void CachedStorageArea::RemoveItem(const String& key, Source* source) {
optional_old_value = StringToUint8Vector(old_value, value_format);
KURL page_url = source->GetPageUrl();
- String source_id = areas_.at(source);
+ String source_id = areas_->at(source);
blink::WebScopedVirtualTimePauser virtual_time_pauser =
source->CreateWebScopedVirtualTimePauser(
@@ -179,16 +177,13 @@ void CachedStorageArea::RemoveItem(const String& key, Source* source) {
WTF::Bind(&CachedStorageArea::OnRemoveItemComplete,
weak_factory_.GetWeakPtr(), key,
std::move(virtual_time_pauser)));
- if (IsSessionStorage()) {
- for (const auto& area : areas_) {
- if (area.key != source)
- area.key->EnqueueStorageEvent(key, old_value, String(), page_url);
- }
- }
+
+ if (IsSessionStorage())
+ EnqueueStorageEvent(key, old_value, String(), page_url, source_id);
}
void CachedStorageArea::Clear(Source* source) {
- DCHECK(areas_.Contains(source));
+ DCHECK(areas_->Contains(source));
bool already_empty = false;
if (IsSessionStorage()) {
@@ -202,7 +197,7 @@ void CachedStorageArea::Clear(Source* source) {
ignore_all_mutations_ = true;
KURL page_url = source->GetPageUrl();
- String source_id = areas_.at(source);
+ String source_id = areas_->at(source);
blink::WebScopedVirtualTimePauser virtual_time_pauser =
source->CreateWebScopedVirtualTimePauser(
@@ -213,42 +208,46 @@ void CachedStorageArea::Clear(Source* source) {
PackSource(page_url, source_id),
WTF::Bind(&CachedStorageArea::OnClearComplete, weak_factory_.GetWeakPtr(),
std::move(virtual_time_pauser)));
- if (IsSessionStorage() && !already_empty) {
- for (const auto& area : areas_) {
- if (area.key != source)
- area.key->EnqueueStorageEvent(String(), String(), String(), page_url);
- }
- }
+ if (IsSessionStorage() && !already_empty)
+ EnqueueStorageEvent(String(), String(), String(), page_url, source_id);
}
String CachedStorageArea::RegisterSource(Source* source) {
String id = String::Number(base::RandUint64());
- areas_.insert(source, id);
+ areas_->insert(source, id);
return id;
}
+// LocalStorage constructor.
CachedStorageArea::CachedStorageArea(
scoped_refptr<const SecurityOrigin> origin,
mojo::InterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener)
: origin_(std::move(origin)),
+ inspector_event_listener_(listener),
mojo_area_(area.get()),
mojo_area_ptr_(std::move(area)),
binding_(this),
+ areas_(new HeapHashMap<WeakMember<Source>, String>),
weak_factory_(this) {
mojom::blink::StorageAreaObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequest(&ptr_info), std::move(ipc_runner));
mojo_area_->AddObserver(std::move(ptr_info));
}
+// SessionStorage constructor.
CachedStorageArea::CachedStorageArea(
scoped_refptr<const SecurityOrigin> origin,
mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener)
: origin_(std::move(origin)),
+ inspector_event_listener_(listener),
mojo_area_(area.get()),
mojo_area_associated_ptr_(std::move(area)),
binding_(this),
+ areas_(new HeapHashMap<WeakMember<Source>, String>),
weak_factory_(this) {
mojom::blink::StorageAreaObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequest(&ptr_info), std::move(ipc_runner));
@@ -287,18 +286,14 @@ void CachedStorageArea::KeyDeleted(const Vector<uint8_t>& key,
Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
bool from_local_area = false;
- for (const auto& area : areas_) {
+ String old_value_string =
+ Uint8VectorToString(old_value, FormatOption::kLocalStorageDetectFormat);
+ for (const auto& area : *areas_) {
if (area.value == storage_area_id) {
from_local_area = true;
- } else {
- area.key->EnqueueStorageEvent(
- key_string,
- Uint8VectorToString(old_value,
- FormatOption::kLocalStorageDetectFormat),
- String(), page_url);
+ break;
}
}
-
if (map_ && !from_local_area) {
// This was from another process or the storage area is gone. If the former,
// remove it from our cache if we haven't already changed it and are waiting
@@ -308,6 +303,8 @@ void CachedStorageArea::KeyDeleted(const Vector<uint8_t>& key,
ignore_key_mutations_.find(key_string) == ignore_key_mutations_.end())
map_->RemoveItem(key_string, nullptr);
}
+ EnqueueStorageEvent(key_string, old_value_string, String(), page_url,
+ storage_area_id);
}
void CachedStorageArea::AllDeleted(const String& source) {
@@ -316,14 +313,12 @@ void CachedStorageArea::AllDeleted(const String& source) {
UnpackSource(source, &page_url, &storage_area_id);
bool from_local_area = false;
- for (const auto& area : areas_) {
+ for (const auto& area : *areas_) {
if (area.value == storage_area_id) {
from_local_area = true;
- } else {
- area.key->EnqueueStorageEvent(String(), String(), String(), page_url);
+ break;
}
}
-
if (map_ && !from_local_area && !ignore_all_mutations_) {
auto old = std::move(map_);
map_ = std::make_unique<StorageAreaMap>(
@@ -339,6 +334,7 @@ void CachedStorageArea::AllDeleted(const String& source) {
++iter;
}
}
+ EnqueueStorageEvent(String(), String(), String(), page_url, storage_area_id);
}
void CachedStorageArea::ShouldSendOldValueOnMutations(bool value) {
@@ -361,15 +357,12 @@ void CachedStorageArea::KeyAddedOrChanged(const Vector<uint8_t>& key,
Uint8VectorToString(new_value, FormatOption::kLocalStorageDetectFormat);
bool from_local_area = false;
- for (const auto& area : areas_) {
+ for (const auto& area : *areas_) {
if (area.value == storage_area_id) {
from_local_area = true;
- } else {
- area.key->EnqueueStorageEvent(key_string, old_value, new_value_string,
- page_url);
+ break;
}
}
-
if (map_ && !from_local_area) {
// This was from another process or the storage area is gone. If the former,
// apply it to our cache if we haven't already changed it and are waiting
@@ -382,6 +375,8 @@ void CachedStorageArea::KeyAddedOrChanged(const Vector<uint8_t>& key,
map_->SetItemIgnoringQuota(key_string, new_value_string);
}
}
+ EnqueueStorageEvent(key_string, old_value, new_value_string, page_url,
+ storage_area_id);
}
void CachedStorageArea::OnSetItemComplete(const String& key,
@@ -491,6 +486,24 @@ bool CachedStorageArea::IsSessionStorage() const {
return mojo_area_associated_ptr_.is_bound();
}
+void CachedStorageArea::EnqueueStorageEvent(const String& key,
+ const String& old_value,
+ const String& new_value,
+ const String& url,
+ const String& storage_area_id) {
+ HeapVector<Member<Source>, 1> areas_to_remove_;
+ for (const auto& area : *areas_) {
+ if (area.value != storage_area_id) {
+ bool keep = area.key->EnqueueStorageEvent(key, old_value, new_value, url);
+ if (!keep)
+ areas_to_remove_.push_back(area.key);
+ }
+ }
+ areas_->RemoveAll(areas_to_remove_);
+ inspector_event_listener_->DidDispatchStorageEvent(origin_.get(), key,
+ old_value, new_value);
+}
+
// static
String CachedStorageArea::Uint8VectorToString(const Vector<uint8_t>& input,
FormatOption format_option) {
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
index 006552e5420..fcf1110f69e 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
@@ -38,9 +38,10 @@ class MODULES_EXPORT CachedStorageArea
// should have been registered first by calling RegisterSource.
class Source : public GarbageCollectedMixin {
public:
- virtual ~Source() {}
+ virtual ~Source() = default;
virtual KURL GetPageUrl() const = 0;
- virtual void EnqueueStorageEvent(const String& key,
+ // Return 'true' to continue receiving events, and 'false' to stop.
+ virtual bool EnqueueStorageEvent(const String& key,
const String& old_value,
const String& new_value,
const String& url) = 0;
@@ -49,14 +50,26 @@ class MODULES_EXPORT CachedStorageArea
WebScopedVirtualTimePauser::VirtualTaskDuration duration) = 0;
};
+ // Used to send events to the InspectorDOMStorageAgent.
+ class InspectorEventListener {
+ public:
+ virtual ~InspectorEventListener() = default;
+ virtual void DidDispatchStorageEvent(const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value) = 0;
+ };
+
static scoped_refptr<CachedStorageArea> CreateForLocalStorage(
scoped_refptr<const SecurityOrigin> origin,
mojo::InterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener);
static scoped_refptr<CachedStorageArea> CreateForSessionStorage(
scoped_refptr<const SecurityOrigin> origin,
mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener);
// These correspond to blink::Storage.
unsigned GetLength();
@@ -83,11 +96,13 @@ class MODULES_EXPORT CachedStorageArea
private:
CachedStorageArea(scoped_refptr<const SecurityOrigin> origin,
mojo::InterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener);
CachedStorageArea(
scoped_refptr<const SecurityOrigin> origin,
mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ InspectorEventListener* listener);
friend class RefCounted<CachedStorageArea>;
~CachedStorageArea() override;
@@ -134,12 +149,19 @@ class MODULES_EXPORT CachedStorageArea
FormatOption GetKeyFormat() const;
FormatOption GetValueFormat() const;
+ void EnqueueStorageEvent(const String& key,
+ const String& old_value,
+ const String& new_value,
+ const String& url,
+ const String& storage_area_id);
+
static String Uint8VectorToString(const Vector<uint8_t>& input,
FormatOption format_option);
static Vector<uint8_t> StringToUint8Vector(const String& input,
FormatOption format_option);
scoped_refptr<const SecurityOrigin> origin_;
+ InspectorEventListener* inspector_event_listener_;
std::unique_ptr<StorageAreaMap> map_;
@@ -158,7 +180,7 @@ class MODULES_EXPORT CachedStorageArea
mojo_area_associated_ptr_;
mojo::AssociatedBinding<mojom::blink::StorageAreaObserver> binding_;
- PersistentHeapHashMap<WeakMember<Source>, String> areas_;
+ Persistent<HeapHashMap<WeakMember<Source>, String>> areas_;
base::WeakPtrFactory<CachedStorageArea> weak_factory_;
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
index e38be688b90..c85494858cb 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
@@ -15,7 +15,8 @@ namespace blink {
using FormatOption = CachedStorageArea::FormatOption;
-class CachedStorageAreaTest : public testing::Test {
+class CachedStorageAreaTest : public testing::Test,
+ public CachedStorageArea::InspectorEventListener {
public:
const scoped_refptr<SecurityOrigin> kOrigin =
SecurityOrigin::CreateFromString("http://dom_storage/");
@@ -31,11 +32,11 @@ class CachedStorageAreaTest : public testing::Test {
if (IsSessionStorage()) {
cached_area_ = CachedStorageArea::CreateForSessionStorage(
kOrigin, mock_storage_area_.GetAssociatedInterfacePtr(),
- renderer_scheduler_->IPCTaskRunner());
+ renderer_scheduler_->IPCTaskRunner(), this);
} else {
cached_area_ = CachedStorageArea::CreateForLocalStorage(
kOrigin, mock_storage_area_.GetInterfacePtr(),
- renderer_scheduler_->IPCTaskRunner());
+ renderer_scheduler_->IPCTaskRunner(), this);
}
source_area_ = new FakeAreaSource(kPageUrl);
source_area_id_ = cached_area_->RegisterSource(source_area_);
@@ -44,6 +45,11 @@ class CachedStorageAreaTest : public testing::Test {
cached_area_->RegisterSource(source_area2_);
}
+ void DidDispatchStorageEvent(const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value) override {}
+
virtual bool IsSessionStorage() { return false; }
bool IsCacheLoaded() { return cached_area_->map_.get(); }
diff --git a/chromium/third_party/blink/renderer/modules/storage/docs/ownership.png b/chromium/third_party/blink/renderer/modules/storage/docs/ownership.png
new file mode 100644
index 00000000000..a001516f503
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/docs/ownership.png
Binary files differ
diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
index 848aebe7a10..e62490bd038 100644
--- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc
@@ -12,8 +12,9 @@
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/storage/storage_area.h"
+#include "third_party/blink/renderer/modules/storage/storage_controller.h"
#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
-#include "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -88,9 +89,8 @@ StorageArea* DOMWindowStorage::sessionStorage(
if (!page)
return nullptr;
- auto storage_area =
- StorageNamespaceController::From(page)->SessionStorage()->GetStorageArea(
- document->GetSecurityOrigin());
+ auto storage_area = StorageNamespace::From(page)->GetWebStorageArea(
+ document->GetSecurityOrigin());
session_storage_ =
StorageArea::Create(document->GetFrame(), std::move(storage_area),
StorageArea::StorageType::kSessionStorage);
@@ -136,8 +136,8 @@ StorageArea* DOMWindowStorage::localStorage(
Page* page = document->GetPage();
if (!page || !page->GetSettings().GetLocalStorageEnabled())
return nullptr;
- auto storage_area =
- StorageNamespace::LocalStorageArea(document->GetSecurityOrigin());
+ auto storage_area = StorageController::GetInstance()->GetWebLocalStorageArea(
+ document->GetSecurityOrigin());
local_storage_ =
StorageArea::Create(document->GetFrame(), std::move(storage_area),
StorageArea::StorageType::kLocalStorage);
diff --git a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
index 0f48ab2f9dd..708b67262c5 100644
--- a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc
@@ -35,9 +35,10 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/inspected_frames.h"
#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
#include "third_party/blink/renderer/modules/storage/storage_area.h"
+#include "third_party/blink/renderer/modules/storage/storage_controller.h"
#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
-#include "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -74,9 +75,11 @@ void InspectorDOMStorageAgent::Restore() {
}
void InspectorDOMStorageAgent::InnerEnable() {
- if (StorageNamespaceController* controller = StorageNamespaceController::From(
- inspected_frames_->Root()->GetPage()))
- controller->SetInspectorAgent(this);
+ StorageController::GetInstance()->AddLocalStorageInspectorStorageAgent(this);
+ StorageNamespace* ns =
+ StorageNamespace::From(inspected_frames_->Root()->GetPage());
+ if (ns)
+ ns->AddInspectorStorageAgent(this);
}
Response InspectorDOMStorageAgent::enable() {
@@ -91,9 +94,12 @@ Response InspectorDOMStorageAgent::disable() {
if (!enabled_.Get())
return Response::OK();
enabled_.Set(false);
- if (StorageNamespaceController* controller = StorageNamespaceController::From(
- inspected_frames_->Root()->GetPage()))
- controller->SetInspectorAgent(nullptr);
+ StorageController::GetInstance()->RemoveLocalStorageInspectorStorageAgent(
+ this);
+ StorageNamespace* ns =
+ StorageNamespace::From(inspected_frames_->Root()->GetPage());
+ if (ns)
+ ns->RemoveInspectorStorageAgent(this);
return Response::OK();
}
@@ -213,23 +219,25 @@ Response InspectorDOMStorageAgent::FindStorageArea(
if (is_local_storage) {
if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessLocalStorage())
return Response::Error("Security origin cannot access local storage");
- storage_area =
- StorageArea::Create(frame,
- StorageNamespace::LocalStorageArea(
- frame->GetDocument()->GetSecurityOrigin()),
- StorageArea::StorageType::kLocalStorage);
+ storage_area = StorageArea::Create(
+ frame,
+ StorageController::GetInstance()->GetWebLocalStorageArea(
+ frame->GetDocument()->GetSecurityOrigin()),
+ StorageArea::StorageType::kLocalStorage);
return Response::OK();
}
if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessSessionStorage())
return Response::Error("Security origin cannot access session storage");
- StorageNamespace* session_storage =
- StorageNamespaceController::From(frame->GetPage())->SessionStorage();
- if (!session_storage)
+ StorageNamespace* session_namespace =
+ StorageNamespace::From(frame->GetPage());
+ if (!session_namespace)
return Response::Error("SessionStorage is not supported");
+ DCHECK(session_namespace->IsSessionStorage());
+
storage_area =
StorageArea::Create(frame,
- session_storage->GetStorageArea(
+ session_namespace->GetWebStorageArea(
frame->GetDocument()->GetSecurityOrigin()),
StorageArea::StorageType::kSessionStorage);
return Response::OK();
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
index 15d31039c25..9aa7c7a460e 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -27,14 +27,16 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/web_storage_area.h"
+#include "third_party/blink/public/platform/web_storage_namespace.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/storage/dom_window_storage.h"
#include "third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h"
+#include "third_party/blink/renderer/modules/storage/storage_controller.h"
#include "third_party/blink/renderer/modules/storage/storage_event.h"
#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
-#include "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -166,12 +168,8 @@ bool StorageArea::CanAccessStorage() const {
if (did_check_can_access_storage_)
return can_access_storage_cached_result_;
- StorageNamespaceController* controller =
- StorageNamespaceController::From(frame->GetPage());
- if (!controller)
- return false;
can_access_storage_cached_result_ =
- controller->CanAccessStorageArea(frame, storage_type_);
+ StorageController::CanAccessStorageArea(frame, storage_type_);
did_check_can_access_storage_ = true;
return can_access_storage_cached_result_;
}
@@ -179,14 +177,11 @@ bool StorageArea::CanAccessStorage() const {
namespace {
Page* FindPageWithSessionStorageNamespace(
const WebStorageNamespace& session_namespace) {
- // Iterate over all pages that have a StorageNamespaceController supplement.
+ // Iterate over all pages that have a StorageNamespace supplement.
+ String namespace_str = session_namespace.GetNamespaceId();
for (Page* page : Page::OrdinaryPages()) {
- const bool kDontCreateIfMissing = false;
- StorageNamespace* storage_namespace =
- StorageNamespaceController::From(page)->SessionStorage(
- kDontCreateIfMissing);
- if (storage_namespace &&
- storage_namespace->IsSameNamespace(session_namespace))
+ StorageNamespace* storage_namespace = StorageNamespace::From(page);
+ if (storage_namespace && storage_namespace->namespace_id() == namespace_str)
return page;
}
return nullptr;
@@ -206,7 +201,7 @@ void StorageArea::DispatchLocalStorageEvent(
const SecurityOrigin* security_origin,
const KURL& page_url,
WebStorageArea* source_area_instance) {
- // Iterate over all pages that have a StorageNamespaceController supplement.
+ // Iterate over all pages that have a LocalStorage area created.
for (Page* page : Page::OrdinaryPages()) {
for (Frame* frame = page->MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
@@ -229,12 +224,8 @@ void StorageArea::DispatchLocalStorageEvent(
TaskType::kDOMManipulation);
}
}
- if (InspectorDOMStorageAgent* agent =
- StorageNamespaceController::From(page)->InspectorAgent()) {
- agent->DidDispatchDOMStorageEvent(key, old_value, new_value,
- StorageType::kLocalStorage,
- security_origin);
- }
+ StorageController::GetInstance()->DidDispatchLocalStorageEvent(
+ security_origin, key, old_value, new_value);
}
}
@@ -270,12 +261,8 @@ void StorageArea::DispatchSessionStorageEvent(
TaskType::kDOMManipulation);
}
}
- if (InspectorDOMStorageAgent* agent =
- StorageNamespaceController::From(page)->InspectorAgent()) {
- agent->DidDispatchDOMStorageEvent(key, old_value, new_value,
- StorageType::kSessionStorage,
- security_origin);
- }
+ StorageNamespace::From(page)->DidDispatchStorageEvent(security_origin, key,
+ old_value, new_value);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc
new file mode 100644
index 00000000000..855e3ba7254
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc
@@ -0,0 +1,170 @@
+// 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 "third_party/blink/renderer/modules/storage/storage_controller.h"
+
+#include "base/feature_list.h"
+#include "base/sys_info.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_storage_area.h"
+#include "third_party/blink/public/platform/web_storage_namespace.h"
+#include "third_party/blink/renderer/core/frame/content_settings_client.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
+#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
+
+namespace blink {
+namespace {
+
+#define STATIC_ASSERT_MATCHING_ENUM(enum_name1, enum_name2) \
+ static_assert(static_cast<int>(enum_name1) == static_cast<int>(enum_name2), \
+ "mismatching enums: " #enum_name1)
+STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kLocalStorage,
+ ContentSettingsClient::StorageType::kLocal);
+STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kSessionStorage,
+ ContentSettingsClient::StorageType::kSession);
+
+const size_t kStorageControllerTotalCacheLimitInBytesLowEnd = 1 * 1024 * 1024;
+const size_t kStorageControllerTotalCacheLimitInBytes = 5 * 1024 * 1024;
+
+mojom::blink::StoragePartitionServicePtr GetAndCreateStorageInterface() {
+ mojom::blink::StoragePartitionServicePtr ptr;
+ Platform::Current()->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&ptr));
+ return ptr;
+}
+} // namespace
+
+// static
+StorageController* StorageController::GetInstance() {
+ DEFINE_STATIC_LOCAL(
+ StorageController, gCachedStorageAreaController,
+ (Platform::Current()->MainThread()->Scheduler()->IPCTaskRunner(),
+ GetAndCreateStorageInterface(),
+ base::SysInfo::IsLowEndDevice()
+ ? kStorageControllerTotalCacheLimitInBytesLowEnd
+ : kStorageControllerTotalCacheLimitInBytes));
+ return &gCachedStorageAreaController;
+}
+
+// static
+bool StorageController::CanAccessStorageArea(LocalFrame* frame,
+ StorageArea::StorageType type) {
+ DCHECK(frame->GetContentSettingsClient());
+ return frame->GetContentSettingsClient()->AllowStorage(
+ static_cast<ContentSettingsClient::StorageType>(type));
+}
+
+StorageController::StorageController(
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ mojom::blink::StoragePartitionServicePtr storage_partition_service,
+ size_t total_cache_limit)
+ : ipc_runner_(std::move(ipc_runner)),
+ namespaces_(new HeapHashMap<String, WeakMember<StorageNamespace>>()),
+ total_cache_limit_(total_cache_limit),
+ storage_partition_service_(std::move(storage_partition_service)) {}
+
+StorageNamespace* StorageController::CreateSessionStorageNamespace(
+ const String& namespace_id) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // There is an edge case where a user closes a tab that has other tabs in the
+ // same process, then restores that tab. The old namespace might still be
+ // around.
+ auto it = namespaces_->find(namespace_id);
+ if (it != namespaces_->end())
+ return it->value;
+ StorageNamespace* ns = nullptr;
+ if (base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)) {
+ ns = new StorageNamespace(this, namespace_id);
+ } else {
+ auto namespace_str = StringUTF8Adaptor(namespace_id);
+ auto web_namespace = Platform::Current()->CreateSessionStorageNamespace(
+ namespace_str.AsStringPiece());
+ if (!web_namespace)
+ return nullptr;
+ ns = new StorageNamespace(std::move(web_namespace));
+ }
+ namespaces_->insert(namespace_id, ns);
+ return ns;
+}
+
+size_t StorageController::TotalCacheSize() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ size_t total = 0;
+ if (local_storage_namespace_)
+ total = local_storage_namespace_->TotalCacheSize();
+ for (const auto& pair : *namespaces_)
+ total += pair.value->TotalCacheSize();
+ return total;
+}
+
+void StorageController::ClearAreasIfNeeded() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (TotalCacheSize() < total_cache_limit_)
+ return;
+ if (local_storage_namespace_)
+ local_storage_namespace_->CleanUpUnusedAreas();
+ for (auto& pair : *namespaces_)
+ pair.value->CleanUpUnusedAreas();
+}
+
+scoped_refptr<CachedStorageArea> StorageController::GetLocalStorageArea(
+ const SecurityOrigin* origin) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ CHECK(base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
+ EnsureLocalStorageNamespaceCreated();
+ return local_storage_namespace_->GetCachedArea(origin);
+}
+
+std::unique_ptr<WebStorageArea> StorageController::GetWebLocalStorageArea(
+ const SecurityOrigin* origin) {
+ DCHECK(IsMainThread());
+ CHECK(!base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
+ EnsureLocalStorageNamespaceCreated();
+ return local_storage_namespace_->GetWebStorageArea(origin);
+}
+
+void StorageController::AddLocalStorageInspectorStorageAgent(
+ InspectorDOMStorageAgent* agent) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ EnsureLocalStorageNamespaceCreated();
+ local_storage_namespace_->AddInspectorStorageAgent(agent);
+}
+
+void StorageController::RemoveLocalStorageInspectorStorageAgent(
+ InspectorDOMStorageAgent* agent) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ EnsureLocalStorageNamespaceCreated();
+ local_storage_namespace_->RemoveInspectorStorageAgent(agent);
+}
+
+void StorageController::DidDispatchLocalStorageEvent(
+ const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value) {
+ if (local_storage_namespace_) {
+ local_storage_namespace_->DidDispatchStorageEvent(origin, key, old_value,
+ new_value);
+ }
+}
+
+void StorageController::EnsureLocalStorageNamespaceCreated() {
+ if (local_storage_namespace_)
+ return;
+ if (base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage)) {
+ local_storage_namespace_ = new StorageNamespace(this);
+ } else {
+ local_storage_namespace_ = new StorageNamespace(
+ Platform::Current()->CreateLocalStorageNamespace());
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller.h b/chromium/third_party/blink/renderer/modules/storage/storage_controller.h
new file mode 100644
index 00000000000..f706c84df2f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller.h
@@ -0,0 +1,110 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_
+
+#include <memory>
+
+#include "base/sequence_checker.h"
+#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/storage/storage_area.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+
+class CachedStorageArea;
+class InspectorDOMStorageAgent;
+class LocalFrame;
+class SecurityOrigin;
+class StorageNamespace;
+class WebStorageArea;
+
+// Singleton that manages the creation & accounting for DOMStorage objects. It
+// does this by holding weak references to all session storage namespaces, and
+// owning the local storage namespace internally. The total cache size is
+// exposed with |TotalCacheSize()|, and |ClearAreasIfNeeded()| will - if our
+// total cache size is larger than |total_cache_limit| - clear away any cache
+// areas in live namespaces that no longer have references from Blink objects.
+//
+// SessionStorage StorageNamespace objects are created with
+// |CreateSessionStorageNamespace| and live as a supplement on the Page.
+//
+// The LocalStorage StorageNamespace object is owned internally, and
+// StorageController delegates the following methods to that namespace:
+// GetLocalStorageArea, GetWebLocalStorageArea,
+// AddLocalStorageInspectorStorageAgent,
+// RemoveLocalStorageInspectorStorageAgent, DidDispatchLocalStorageEvent
+class MODULES_EXPORT StorageController {
+ public:
+ // Returns the one global StorageController instance.
+ static StorageController* GetInstance();
+
+ static bool CanAccessStorageArea(LocalFrame* frame,
+ StorageArea::StorageType type);
+
+ // Visible for testing.
+ StorageController(
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ mojom::blink::StoragePartitionServicePtr storage_partition_service,
+ size_t total_cache_limit);
+
+ // Creates a new StorageNamespace for Session storage, and holds a weak
+ // reference for accounting & clearing. If there is already a StorageNamespace
+ // created for the given id, it is returned.
+ StorageNamespace* CreateSessionStorageNamespace(const String& namespace_id);
+
+ // Returns the total size of all cached areas in namespaces this controller
+ // knows of.
+ size_t TotalCacheSize() const;
+
+ // Cleans up unused areas if the total cache size is over the cache limit.
+ void ClearAreasIfNeeded();
+
+ // Methods that delegate to the internal SessionNamespace used for
+ // LocalStorage:
+
+ scoped_refptr<CachedStorageArea> GetLocalStorageArea(const SecurityOrigin*);
+ // TODO(dmurph): Remove this once DOMStorage is Onion Soupified.
+ std::unique_ptr<WebStorageArea> GetWebLocalStorageArea(const SecurityOrigin*);
+ void AddLocalStorageInspectorStorageAgent(InspectorDOMStorageAgent* agent);
+ void RemoveLocalStorageInspectorStorageAgent(InspectorDOMStorageAgent* agent);
+ // TODO(dmurph): Remove this once DOMStorage is Onion Soupified.
+ void DidDispatchLocalStorageEvent(const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value);
+
+ mojom::blink::StoragePartitionService* storage_partition_service() const {
+ return storage_partition_service_.get();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() {
+ return ipc_runner_;
+ }
+
+ private:
+ void EnsureLocalStorageNamespaceCreated();
+
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner_;
+ Persistent<HeapHashMap<String, WeakMember<StorageNamespace>>> namespaces_;
+ Persistent<StorageNamespace> local_storage_namespace_;
+ size_t total_cache_limit_;
+
+ // Onion-soup state.
+ mojom::blink::StoragePartitionServicePtr storage_partition_service_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc b/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc
new file mode 100644
index 00000000000..ff0d8a140a4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc
@@ -0,0 +1,176 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/storage/storage_controller.h"
+
+#include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
+#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
+#include "third_party/blink/renderer/modules/storage/testing/fake_area_source.h"
+#include "third_party/blink/renderer/modules/storage/testing/mock_storage_area.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/uuid.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+namespace {
+
+const size_t kTestCacheLimit = 100;
+class MockStoragePartitionService
+ : public mojom::blink::StoragePartitionService {
+ public:
+ void OpenLocalStorage(const scoped_refptr<const SecurityOrigin>& origin,
+ mojom::blink::StorageAreaRequest request) override {}
+
+ void OpenSessionStorage(
+ const String& namespace_id,
+ mojom::blink::SessionStorageNamespaceRequest request) override {
+ session_storage_opens++;
+ }
+
+ void GetSessionStorageUsage(int32_t* out) const {
+ *out = session_storage_opens;
+ }
+
+ int32_t session_storage_opens = 0;
+};
+
+} // namespace
+
+TEST(StorageControllerTest, CacheLimit) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kOnionSoupDOMStorage);
+ const auto kOrigin = SecurityOrigin::CreateFromString("http://dom_storage1/");
+ const auto kOrigin2 =
+ SecurityOrigin::CreateFromString("http://dom_storage2/");
+ const auto kOrigin3 =
+ SecurityOrigin::CreateFromString("http://dom_storage3/");
+ const String kKey("key");
+ const String kValue("value");
+ const KURL kPageUrl("http://dom_storage/page");
+ Persistent<FakeAreaSource> source_area = new FakeAreaSource(kPageUrl);
+
+ blink::scheduler::FakeRendererScheduler renderer_scheduler;
+
+ mojom::blink::StoragePartitionServicePtr storage_partition_service_ptr;
+ PostCrossThreadTask(
+ *base::CreateSequencedTaskRunnerWithTraits({}), FROM_HERE,
+ CrossThreadBind(
+ [](mojom::blink::StoragePartitionServiceRequest request) {
+ mojo::MakeStrongBinding(
+ std::make_unique<MockStoragePartitionService>(),
+ std::move(request));
+ },
+ WTF::Passed(MakeRequest(&storage_partition_service_ptr))));
+
+ StorageController controller(renderer_scheduler.IPCTaskRunner(),
+ std::move(storage_partition_service_ptr),
+ kTestCacheLimit);
+
+ auto cached_area1 = controller.GetLocalStorageArea(kOrigin.get());
+ cached_area1->RegisterSource(source_area);
+ cached_area1->SetItem(kKey, kValue, source_area);
+ const auto* area1_ptr = cached_area1.get();
+ size_t expected_total = (kKey.length() + kValue.length()) * 2;
+ EXPECT_EQ(expected_total, cached_area1->memory_used());
+ EXPECT_EQ(expected_total, controller.TotalCacheSize());
+ cached_area1 = nullptr;
+
+ auto cached_area2 = controller.GetLocalStorageArea(kOrigin2.get());
+ cached_area2->RegisterSource(source_area);
+ cached_area2->SetItem(kKey, kValue, source_area);
+ // Area for kOrigin should still be alive.
+ EXPECT_EQ(2 * cached_area2->memory_used(), controller.TotalCacheSize());
+ EXPECT_EQ(area1_ptr, controller.GetLocalStorageArea(kOrigin.get()));
+
+ String long_value(Vector<UChar>(kTestCacheLimit, 'a'));
+ cached_area2->SetItem(kKey, long_value, source_area);
+ // Cache is cleared when a new area is opened.
+ auto cached_area3 = controller.GetLocalStorageArea(kOrigin3.get());
+ EXPECT_EQ(cached_area2->memory_used(), controller.TotalCacheSize());
+}
+
+TEST(StorageControllerTest, CacheLimitSessionStorage) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kOnionSoupDOMStorage);
+ const String kNamespace1 = CreateCanonicalUUIDString();
+ const String kNamespace2 = CreateCanonicalUUIDString();
+ const auto kOrigin = SecurityOrigin::CreateFromString("http://dom_storage1/");
+ const auto kOrigin2 =
+ SecurityOrigin::CreateFromString("http://dom_storage2/");
+ const auto kOrigin3 =
+ SecurityOrigin::CreateFromString("http://dom_storage3/");
+ const String kKey("key");
+ const String kValue("value");
+ const KURL kPageUrl("http://dom_storage/page");
+
+ Persistent<FakeAreaSource> source_area = new FakeAreaSource(kPageUrl);
+
+ blink::scheduler::FakeRendererScheduler renderer_scheduler;
+ auto task_runner = base::CreateSequencedTaskRunnerWithTraits({});
+
+ auto mock_storage_partition_service =
+ std::make_unique<MockStoragePartitionService>();
+ MockStoragePartitionService* storage_partition_ptr =
+ mock_storage_partition_service.get();
+
+ mojom::blink::StoragePartitionServicePtr storage_partition_service_ptr;
+ PostCrossThreadTask(
+ *task_runner, FROM_HERE,
+ CrossThreadBind(
+ [](std::unique_ptr<MockStoragePartitionService> storage_partition_ptr,
+ mojom::blink::StoragePartitionServiceRequest request) {
+ mojo::MakeStrongBinding(std::move(storage_partition_ptr),
+ std::move(request));
+ },
+ WTF::Passed(std::move(mock_storage_partition_service)),
+ WTF::Passed(MakeRequest(&storage_partition_service_ptr))));
+ StorageController controller(renderer_scheduler.IPCTaskRunner(),
+ std::move(storage_partition_service_ptr),
+ kTestCacheLimit);
+
+ StorageNamespace* ns1 = controller.CreateSessionStorageNamespace(kNamespace1);
+ StorageNamespace* ns2 = controller.CreateSessionStorageNamespace(kNamespace2);
+
+ auto cached_area1 = ns1->GetCachedArea(kOrigin.get());
+ cached_area1->RegisterSource(source_area);
+ cached_area1->SetItem(kKey, kValue, source_area);
+ const auto* area1_ptr = cached_area1.get();
+ size_t expected_total = (kKey.length() + kValue.length()) * 2;
+ EXPECT_EQ(expected_total, cached_area1->memory_used());
+ EXPECT_EQ(expected_total, controller.TotalCacheSize());
+ cached_area1 = nullptr;
+
+ auto cached_area2 = ns2->GetCachedArea(kOrigin2.get());
+ cached_area2->RegisterSource(source_area);
+ cached_area2->SetItem(kKey, kValue, source_area);
+ // Area for kOrigin should still be alive.
+ EXPECT_EQ(2 * cached_area2->memory_used(), controller.TotalCacheSize());
+ EXPECT_EQ(area1_ptr, ns1->GetCachedArea(kOrigin.get()));
+
+ String long_value(Vector<UChar>(kTestCacheLimit, 'a'));
+ cached_area2->SetItem(kKey, long_value, source_area);
+ // Cache is cleared when a new area is opened.
+ auto cached_area3 = ns1->GetCachedArea(kOrigin3.get());
+ EXPECT_EQ(cached_area2->memory_used(), controller.TotalCacheSize());
+
+ int32_t opens = 0;
+ {
+ base::RunLoop loop;
+ task_runner->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(&MockStoragePartitionService::GetSessionStorageUsage,
+ base::Unretained(storage_partition_ptr), &opens),
+ loop.QuitClosure());
+ loop.Run();
+ }
+ EXPECT_EQ(opens, 2);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
index 617817f297f..fdc44083b4c 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
@@ -27,42 +27,171 @@
#include <memory>
+#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_storage_area.h"
#include "third_party/blink/public/platform/web_storage_namespace.h"
+#include "third_party/blink/public/web/web_view_client.h"
+#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
+#include "third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h"
+#include "third_party/blink/renderer/modules/storage/storage_area.h"
+#include "third_party/blink/renderer/modules/storage/storage_controller.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
+const char StorageNamespace::kSupplementName[] = "SessionStorageNamespace";
+
+StorageNamespace::StorageNamespace(StorageController* controller)
+ : controller_(controller) {
+ CHECK(base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
+}
+StorageNamespace::StorageNamespace(StorageController* controller,
+ const String& namespace_id)
+ : controller_(controller), namespace_id_(namespace_id) {
+ CHECK(base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
+}
+
StorageNamespace::StorageNamespace(
std::unique_ptr<WebStorageNamespace> web_storage_namespace)
- : web_storage_namespace_(std::move(web_storage_namespace)) {}
+ : controller_(nullptr),
+ namespace_id_(web_storage_namespace->GetNamespaceId()),
+ web_storage_namespace_(std::move(web_storage_namespace)) {
+ CHECK(!base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
+}
StorageNamespace::~StorageNamespace() = default;
-std::unique_ptr<WebStorageArea> StorageNamespace::LocalStorageArea(
- const SecurityOrigin* origin) {
- DCHECK(IsMainThread());
- static std::unique_ptr<WebStorageNamespace> local_storage_namespace = nullptr;
- if (!local_storage_namespace)
- local_storage_namespace =
- Platform::Current()->CreateLocalStorageNamespace();
- return base::WrapUnique(
- local_storage_namespace->CreateStorageArea(WebSecurityOrigin(origin)));
+// static
+void StorageNamespace::ProvideSessionStorageNamespaceTo(Page& page,
+ WebViewClient* client) {
+ if (client) {
+ if (client->GetSessionStorageNamespaceId().empty())
+ return;
+ auto* ss_namespace =
+ StorageController::GetInstance()->CreateSessionStorageNamespace(
+ String(client->GetSessionStorageNamespaceId().data(),
+ client->GetSessionStorageNamespaceId().size()));
+ if (!ss_namespace)
+ return;
+ ProvideTo(page, ss_namespace);
+ }
+}
+
+scoped_refptr<CachedStorageArea> StorageNamespace::GetCachedArea(
+ const SecurityOrigin* origin_ptr) {
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class CacheMetrics {
+ kMiss = 0, // Area not in cache.
+ kHit = 1, // Area with refcount = 0 loaded from cache.
+ kUnused = 2, // Cache was not used. Area had refcount > 0.
+ kMaxValue = kUnused,
+ };
+
+ CacheMetrics metric = CacheMetrics::kMiss;
+ scoped_refptr<CachedStorageArea> result;
+ auto cache_it = cached_areas_.find(origin_ptr);
+ if (cache_it != cached_areas_.end()) {
+ metric = cache_it->value->HasOneRef() ? CacheMetrics::kHit
+ : CacheMetrics::kUnused;
+ result = cache_it->value;
+ }
+ if (IsSessionStorage())
+ LOCAL_HISTOGRAM_ENUMERATION("SessionStorage.RendererAreaCacheHit", metric);
+ else
+ UMA_HISTOGRAM_ENUMERATION("LocalStorage.RendererAreaCacheHit", metric);
+
+ if (result)
+ return result;
+
+ scoped_refptr<const SecurityOrigin> origin(origin_ptr);
+
+ controller_->ClearAreasIfNeeded();
+ if (IsSessionStorage()) {
+ EnsureConnected();
+ mojom::blink::StorageAreaAssociatedPtr area_ptr;
+ namespace_->OpenArea(origin,
+ MakeRequest(&area_ptr, controller_->IPCTaskRunner()));
+ result = CachedStorageArea::CreateForSessionStorage(
+ origin, std::move(area_ptr), controller_->IPCTaskRunner(), this);
+ } else {
+ mojom::blink::StorageAreaPtr area_ptr;
+ controller_->storage_partition_service()->OpenLocalStorage(
+ origin, MakeRequest(&area_ptr, controller_->IPCTaskRunner()));
+ result = CachedStorageArea::CreateForLocalStorage(
+ origin, std::move(area_ptr), controller_->IPCTaskRunner(), this);
+ }
+ cached_areas_.insert(std::move(origin), result);
+ return result;
}
-std::unique_ptr<WebStorageArea> StorageNamespace::GetStorageArea(
+void StorageNamespace::CloneTo(const String& target) {
+ DCHECK(IsSessionStorage()) << "Cannot clone a local storage namespace.";
+ EnsureConnected();
+ namespace_->Clone(target);
+}
+
+size_t StorageNamespace::TotalCacheSize() const {
+ size_t total = 0;
+ for (const auto& it : cached_areas_)
+ total += it.value->memory_used();
+ return total;
+}
+
+void StorageNamespace::CleanUpUnusedAreas() {
+ Vector<const SecurityOrigin*, 16> to_remove;
+ for (const auto& area : cached_areas_) {
+ if (area.value->HasOneRef())
+ to_remove.push_back(area.key.get());
+ }
+ cached_areas_.RemoveAll(to_remove);
+}
+
+void StorageNamespace::AddInspectorStorageAgent(
+ InspectorDOMStorageAgent* agent) {
+ inspector_agents_.insert(agent);
+}
+void StorageNamespace::RemoveInspectorStorageAgent(
+ InspectorDOMStorageAgent* agent) {
+ inspector_agents_.erase(agent);
+}
+
+void StorageNamespace::Trace(Visitor* visitor) {
+ visitor->Trace(inspector_agents_);
+ Supplement<Page>::Trace(visitor);
+}
+
+void StorageNamespace::DidDispatchStorageEvent(const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value) {
+ for (InspectorDOMStorageAgent* agent : inspector_agents_) {
+ agent->DidDispatchDOMStorageEvent(
+ key, old_value, new_value,
+ IsSessionStorage() ? StorageArea::StorageType::kSessionStorage
+ : StorageArea::StorageType::kLocalStorage,
+ origin);
+ }
+}
+std::unique_ptr<WebStorageArea> StorageNamespace::GetWebStorageArea(
const SecurityOrigin* origin) {
+ CHECK(!base::FeatureList::IsEnabled(features::kOnionSoupDOMStorage));
return base::WrapUnique(
web_storage_namespace_->CreateStorageArea(WebSecurityOrigin(origin)));
}
-bool StorageNamespace::IsSameNamespace(
- const WebStorageNamespace& session_namespace) const {
- return web_storage_namespace_ &&
- web_storage_namespace_->IsSameNamespace(session_namespace);
+void StorageNamespace::EnsureConnected() {
+ DCHECK(IsSessionStorage());
+ if (namespace_)
+ return;
+ auto request = MakeRequest(&namespace_, controller_->IPCTaskRunner());
+ controller_->storage_partition_service()->OpenSessionStorage(
+ namespace_id_, std::move(request));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
index c3b3be0ebcd..4c316e429b9 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
@@ -27,29 +27,112 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_NAMESPACE_H_
#include <memory>
+
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink.h"
#include "third_party/blink/public/platform/web_storage_area.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class WebStorageNamespace;
+class InspectorDOMStorageAgent;
+class StorageController;
class SecurityOrigin;
+class WebStorageNamespace;
+class WebViewClient;
-class MODULES_EXPORT StorageNamespace {
- USING_FAST_MALLOC(StorageNamespace);
+// Contains DOMStorage storage areas for origins & handles inspector agents. A
+// namespace is either a SessionStorage namespace with a namespace_id, or a
+// LocalStorage namespace with no (or an empty) namespace_id. The LocalStorage
+// version of the StorageNamespace lives in the StorageController.
+// InspectorDOMStorageAgents that are registered on this object are notified
+// through |DidDispatchStorageEvent|.
+//
+// With the kOnionSoupDOMStorage flag off:
+// The StorageNamespace basically delegates calls to GetWebStorageArea to the
+// internal WebStorageNamespace. |GetWebStorageArea| is used to get the storage
+// area for an origin.
+//
+// With the kOnionSoupDOMStorage flag on:
+// The StorageNamespace for SessioStorage supplement the Page. |GetCachedArea|
+// is used to get the storage area for an origin.
+class MODULES_EXPORT StorageNamespace final
+ : public GarbageCollectedFinalized<StorageNamespace>,
+ public Supplement<Page>,
+ public CachedStorageArea::InspectorEventListener {
+ USING_GARBAGE_COLLECTED_MIXIN(StorageNamespace);
public:
- explicit StorageNamespace(std::unique_ptr<WebStorageNamespace>);
- ~StorageNamespace();
+ static const char kSupplementName[];
+
+ static void ProvideSessionStorageNamespaceTo(Page&, WebViewClient*);
+ static StorageNamespace* From(Page* page) {
+ return Supplement<Page>::From<StorageNamespace>(page);
+ }
+
+ // Constructor for an onion-souped LocalStorage namespace.
+ StorageNamespace(StorageController*);
+ // Constructor for an onion-souped SessionStorage namespace.
+ StorageNamespace(StorageController*, const String& namespace_id);
+ // Pre-onion-soup constructor. WebStorageNamespace must not be null.
+ StorageNamespace(std::unique_ptr<WebStorageNamespace>);
+
+ ~StorageNamespace() override;
+
+ // TODO(dmurph): Remove this once Onion Soupified.
+ const String& namespace_id() { return namespace_id_; }
+ // TODO(dmurph): Remove this once Onion Soupified.
+ std::unique_ptr<WebStorageArea> GetWebStorageArea(const SecurityOrigin*);
+
+ scoped_refptr<CachedStorageArea> GetCachedArea(const SecurityOrigin* origin);
- static std::unique_ptr<WebStorageArea> LocalStorageArea(
- const SecurityOrigin*);
- std::unique_ptr<WebStorageArea> GetStorageArea(const SecurityOrigin*);
+ // Only valid to call this if |this| and |target| are session storage
+ // namespaces.
+ void CloneTo(const String& target);
- bool IsSameNamespace(const WebStorageNamespace& session_namespace) const;
+ size_t TotalCacheSize() const;
+
+ // Removes any CachedStorageAreas that aren't referenced by any source.
+ void CleanUpUnusedAreas();
+
+ bool IsSessionStorage() const { return !namespace_id_.IsEmpty(); }
+
+ void AddInspectorStorageAgent(InspectorDOMStorageAgent* agent);
+ void RemoveInspectorStorageAgent(InspectorDOMStorageAgent* agent);
+
+ void Trace(Visitor* visitor) override;
+
+ // Iterates all of the inspector agents and calls
+ // |DidDispatchDOMStorageEvent|.
+ void DidDispatchStorageEvent(const SecurityOrigin* origin,
+ const String& key,
+ const String& old_value,
+ const String& new_value) override;
private:
+ void EnsureConnected();
+
+ HeapHashSet<WeakMember<InspectorDOMStorageAgent>> inspector_agents_;
+
+ // Onion-souped storage wiring, not turned on yet.
+ // Lives globally.
+ StorageController* controller_;
+ String namespace_id_;
+ mojom::blink::SessionStorageNamespacePtr namespace_;
+ HashMap<scoped_refptr<const SecurityOrigin>,
+ scoped_refptr<CachedStorageArea>,
+ SecurityOriginHash>
+ cached_areas_;
+
+ // Pre-onion-soup storage wiring, currently active.
std::unique_ptr<WebStorageNamespace> web_storage_namespace_;
};
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.cc
deleted file mode 100644
index 9ee5d2880ba..00000000000
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.cc
+++ /dev/null
@@ -1,70 +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 "third_party/blink/renderer/modules/storage/storage_namespace_controller.h"
-
-#include <memory>
-
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_storage_namespace.h"
-#include "third_party/blink/public/web/web_view_client.h"
-#include "third_party/blink/renderer/core/frame/content_settings_client.h"
-#include "third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h"
-#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
-
-namespace blink {
-
-#define STATIC_ASSERT_MATCHING_ENUM(enum_name1, enum_name2) \
- static_assert(static_cast<int>(enum_name1) == static_cast<int>(enum_name2), \
- "mismatching enums: " #enum_name1)
-STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kLocalStorage,
- ContentSettingsClient::StorageType::kLocal);
-STATIC_ASSERT_MATCHING_ENUM(StorageArea::StorageType::kSessionStorage,
- ContentSettingsClient::StorageType::kSession);
-
-const char StorageNamespaceController::kSupplementName[] =
- "StorageNamespaceController";
-
-StorageNamespaceController::StorageNamespaceController(WebViewClient* client)
- : inspector_agent_(nullptr), web_view_client_(client) {}
-
-StorageNamespaceController::~StorageNamespaceController() = default;
-
-void StorageNamespaceController::Trace(blink::Visitor* visitor) {
- Supplement<Page>::Trace(visitor);
- visitor->Trace(inspector_agent_);
-}
-
-StorageNamespace* StorageNamespaceController::SessionStorage(
- bool optional_create) {
- if (!session_storage_ && optional_create)
- session_storage_ = CreateSessionStorageNamespace();
- return session_storage_.get();
-}
-
-void StorageNamespaceController::ProvideStorageNamespaceTo(
- Page& page,
- WebViewClient* client) {
- ProvideTo(page, new StorageNamespaceController(client));
-}
-
-std::unique_ptr<StorageNamespace>
-StorageNamespaceController::CreateSessionStorageNamespace() {
- if (!web_view_client_)
- return nullptr;
-
- return std::make_unique<StorageNamespace>(
- Platform::Current()->CreateSessionStorageNamespace(
- web_view_client_->GetSessionStorageNamespaceId()));
-}
-
-bool StorageNamespaceController::CanAccessStorageArea(
- LocalFrame* frame,
- StorageArea::StorageType type) const {
- DCHECK(frame->GetContentSettingsClient());
- return frame->GetContentSettingsClient()->AllowStorage(
- static_cast<ContentSettingsClient::StorageType>(type));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.h b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.h
deleted file mode 100644
index b53f45859fd..00000000000
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_controller.h
+++ /dev/null
@@ -1,58 +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 THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_NAMESPACE_CONTROLLER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_NAMESPACE_CONTROLLER_H_
-
-#include <memory>
-
-#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/storage/storage_area.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-class InspectorDOMStorageAgent;
-class StorageNamespace;
-class WebViewClient;
-
-class MODULES_EXPORT StorageNamespaceController final
- : public GarbageCollectedFinalized<StorageNamespaceController>,
- public Supplement<Page> {
- USING_GARBAGE_COLLECTED_MIXIN(StorageNamespaceController);
-
- public:
- static const char kSupplementName[];
-
- StorageNamespace* SessionStorage(bool optional_create = true);
- ~StorageNamespaceController();
-
- bool CanAccessStorageArea(LocalFrame*, StorageArea::StorageType) const;
-
- static void ProvideStorageNamespaceTo(Page&, WebViewClient*);
- static StorageNamespaceController* From(Page* page) {
- return Supplement<Page>::From<StorageNamespaceController>(page);
- }
-
- void Trace(blink::Visitor*) override;
-
- InspectorDOMStorageAgent* InspectorAgent() { return inspector_agent_; }
- void SetInspectorAgent(InspectorDOMStorageAgent* agent) {
- inspector_agent_ = agent;
- }
-
- private:
- explicit StorageNamespaceController(WebViewClient*);
-
- std::unique_ptr<StorageNamespace> CreateSessionStorageNamespace();
-
- std::unique_ptr<StorageNamespace> session_storage_;
- Member<InspectorDOMStorageAgent> inspector_agent_;
- WebViewClient* web_view_client_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_NAMESPACE_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc
new file mode 100644
index 00000000000..ca24c518276
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc
@@ -0,0 +1,96 @@
+// 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 "third_party/blink/renderer/modules/storage/storage_namespace.h"
+#include <third_party/blink/renderer/modules/storage/storage_controller.h>
+
+#include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
+#include "third_party/blink/renderer/modules/storage/testing/fake_area_source.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/uuid.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+namespace {
+class NoopStoragePartitionService
+ : public mojom::blink::StoragePartitionService {
+ public:
+ void OpenLocalStorage(const scoped_refptr<const SecurityOrigin>& origin,
+ mojom::blink::StorageAreaRequest request) override {}
+
+ void OpenSessionStorage(
+ const String& namespace_id,
+ mojom::blink::SessionStorageNamespaceRequest request) override {}
+};
+
+} // namespace
+
+class StorageNamespaceTest : public testing::Test {
+ public:
+ const size_t kTestCacheLimit = 100;
+
+ StorageNamespaceTest() {
+ features_.InitAndEnableFeature(features::kOnionSoupDOMStorage);
+ }
+ ~StorageNamespaceTest() override {}
+
+ base::test::ScopedFeatureList features_;
+};
+
+TEST_F(StorageNamespaceTest, BasicStorageAreas) {
+ const auto kOrigin = SecurityOrigin::CreateFromString("http://dom_storage1/");
+ const auto kOrigin2 =
+ SecurityOrigin::CreateFromString("http://dom_storage2/");
+ const auto kOrigin3 =
+ SecurityOrigin::CreateFromString("http://dom_storage3/");
+ const String kKey("key");
+ const String kValue("value");
+ const String kSessionStorageNamespace("abcd");
+ const KURL kPageUrl("http://dom_storage/page");
+ Persistent<FakeAreaSource> source_area = new FakeAreaSource(kPageUrl);
+
+ blink::scheduler::FakeRendererScheduler renderer_scheduler;
+
+ mojom::blink::StoragePartitionServicePtr storage_partition_service_ptr;
+ PostCrossThreadTask(
+ *base::CreateSequencedTaskRunnerWithTraits({}), FROM_HERE,
+ CrossThreadBind(
+ [](mojom::blink::StoragePartitionServiceRequest request) {
+ mojo::MakeStrongBinding(
+ std::make_unique<NoopStoragePartitionService>(),
+ std::move(request));
+ },
+ WTF::Passed(MakeRequest(&storage_partition_service_ptr))));
+
+ StorageController controller(renderer_scheduler.IPCTaskRunner(),
+ std::move(storage_partition_service_ptr),
+ kTestCacheLimit);
+ StorageNamespace* localStorage = new StorageNamespace(&controller);
+ StorageNamespace* sessionStorage =
+ new StorageNamespace(&controller, kSessionStorageNamespace);
+
+ EXPECT_FALSE(localStorage->IsSessionStorage());
+ EXPECT_TRUE(sessionStorage->IsSessionStorage());
+
+ auto cached_area1 = localStorage->GetCachedArea(kOrigin.get());
+ cached_area1->RegisterSource(source_area);
+ cached_area1->SetItem(kKey, kValue, source_area);
+ auto cached_area2 = localStorage->GetCachedArea(kOrigin2.get());
+ cached_area2->RegisterSource(source_area);
+ cached_area2->SetItem(kKey, kValue, source_area);
+ auto cached_area3 = sessionStorage->GetCachedArea(kOrigin3.get());
+ cached_area3->RegisterSource(source_area);
+ cached_area3->SetItem(kKey, kValue, source_area);
+
+ EXPECT_EQ(cached_area1->GetItem(kKey), kValue);
+ EXPECT_EQ(cached_area2->GetItem(kKey), kValue);
+ EXPECT_EQ(cached_area3->GetItem(kKey), kValue);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
index 92e1cf497e4..cbb2886c6dc 100644
--- a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
@@ -19,11 +19,12 @@ class FakeAreaSource : public GarbageCollectedFinalized<FakeAreaSource>,
explicit FakeAreaSource(const KURL& page_url) : page_url_(page_url) {}
KURL GetPageUrl() const override { return page_url_; }
- void EnqueueStorageEvent(const String& key,
+ bool EnqueueStorageEvent(const String& key,
const String& old_value,
const String& new_value,
const String& url) override {
events.push_back(Event{key, old_value, new_value, url});
+ return true;
}
blink::WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
diff --git a/chromium/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc b/chromium/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc
index 4d8a9721a4c..e17c7d029ef 100644
--- a/chromium/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc
+++ b/chromium/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc
@@ -65,21 +65,7 @@ void TimeZoneMonitorClient::OnTimeZoneChange(const String& time_zone_info) {
}
NotifyTimezoneChangeToV8(V8PerIsolateData::MainThreadIsolate());
-
- HashSet<WorkerThread*>& threads = WorkerThread::WorkerThreads();
- HashSet<WorkerBackingThread*> posted;
- for (WorkerThread* thread : threads) {
- // Ensure every WorkerBackingThread(holding one platform thread) only get
- // the task posted once, because one WorkerBackingThread could be shared
- // among multiple WorkerThreads.
- if (posted.Contains(&thread->GetWorkerBackingThread()))
- continue;
- PostCrossThreadTask(*thread->GetTaskRunner(TaskType::kInternalDefault),
- FROM_HERE,
- CrossThreadBind(&NotifyTimezoneChangeOnWorkerThread,
- WTF::CrossThreadUnretained(thread)));
- posted.insert(&thread->GetWorkerBackingThread());
- }
+ WorkerThread::CallOnAllWorkerThreads(&NotifyTimezoneChangeOnWorkerThread);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
index 3381c6414ac..181bac4a60b 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
+++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
@@ -19,7 +19,6 @@
#include "third_party/blink/renderer/modules/vibration/navigator_vibration.h"
-#include "third_party/blink/public/platform/site_engagement.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -32,7 +31,6 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/vibration/vibration_controller.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/histogram.h"
namespace blink {
@@ -129,27 +127,6 @@ void NavigatorVibration::CollectHistogramMetrics(const LocalFrame& frame) {
DEFINE_STATIC_LOCAL(EnumerationHistogram, navigator_vibrate_histogram,
("Vibration.Context", NavigatorVibrationType::kEnumMax));
navigator_vibrate_histogram.Count(type);
-
- switch (frame.GetDocument()->GetEngagementLevel()) {
- case mojom::blink::EngagementLevel::NONE:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementNone);
- break;
- case mojom::blink::EngagementLevel::MINIMAL:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementMinimal);
- break;
- case mojom::blink::EngagementLevel::LOW:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementLow);
- break;
- case mojom::blink::EngagementLevel::MEDIUM:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementMedium);
- break;
- case mojom::blink::EngagementLevel::HIGH:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementHigh);
- break;
- case mojom::blink::EngagementLevel::MAX:
- UseCounter::Count(&frame, WebFeature::kNavigatorVibrateEngagementMax);
- break;
- }
}
VibrationController* NavigatorVibration::Controller(LocalFrame& frame) {
diff --git a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
index ad15980a428..25c1178ad50 100644
--- a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/vr/navigator_vr.h"
#include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -23,7 +24,6 @@
#include "third_party/blink/renderer/modules/vr/vr_get_devices_callback.h"
#include "third_party/blink/renderer/modules/vr/vr_pose.h"
#include "third_party/blink/renderer/modules/xr/xr.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
namespace blink {
@@ -144,7 +144,8 @@ ScriptPromise NavigatorVR::getVRDisplays(ScriptState* script_state) {
script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
kNotAssociatedWithDocumentMessage));
}
- if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebVr)) {
+ if (!GetDocument()->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebVr,
+ ReportOptions::kReportOnFailure)) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
kFeaturePolicyBlockedMessage));
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
index 3a73e9a0f16..17ab044676d 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -398,7 +398,8 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* script_state,
// allowed outside a user gesture so that the presented content may be
// updated.
if (first_present) {
- if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ if (!LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
+ : nullptr)) {
DOMException* exception =
DOMException::Create(DOMExceptionCode::kInvalidStateError,
"API can only be initiated by a user gesture.");
@@ -683,10 +684,11 @@ void VRDisplay::BeginPresent() {
// For GVR, we shut down normal vsync processing during VR presentation.
// Run window.rAF once manually so that applications get a chance to
// schedule a VRDisplay.rAF in case they do so only while presenting.
- if (!pending_vrdisplay_raf_ && !capabilities_->hasExternalDisplay()) {
+ if (doc && !pending_vrdisplay_raf_ && !capabilities_->hasExternalDisplay()) {
TimeTicks timestamp = WTF::CurrentTimeTicks();
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations,
+ doc->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations,
WrapWeakPersistent(this), timestamp));
}
}
@@ -933,7 +935,7 @@ void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason,
std::unique_ptr<UserGestureIndicator> gesture_indicator;
if (reason == device::mojom::blink::VRDisplayEventReason::MOUNTED)
- gesture_indicator = Frame::NotifyUserActivation(doc->GetFrame());
+ gesture_indicator = LocalFrame::NotifyUserActivation(doc->GetFrame());
base::AutoReset<bool> in_activate(&in_display_activate_, true);
@@ -1051,6 +1053,10 @@ void VRDisplay::OnPresentingVSync(
NOTIMPLEMENTED();
}
+ Document* doc = GetDocument();
+ if (!doc)
+ return;
+
// Post a task to handle scheduled animations after the current
// execution context finishes, so that we yield to non-mojo tasks in
// between frames. Executing mojo tasks back to back within the same
@@ -1059,10 +1065,13 @@ void VRDisplay::OnPresentingVSync(
// this is due to WaitForIncomingMethodCall receiving the OnVSync
// but queueing it for immediate execution since it doesn't match
// the interface being waited on.
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledAnimations,
- WrapWeakPersistent(this),
- TimeTicks() + frame_data->time_delta));
+ //
+ // Used kInternalMedia since 1) this is not spec-ed and 2) this is media
+ // related then tasks should not be throttled or frozen in background tabs.
+ doc->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledAnimations,
+ WrapWeakPersistent(this),
+ TimeTicks() + frame_data->time_delta));
}
void VRDisplay::OnNonImmersiveVSync(TimeTicks timestamp) {
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.h b/chromium/third_party/blink/renderer/modules/vr/vr_display.h
index de85257ee3c..429ac4e6f69 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display.h
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.h
@@ -265,21 +265,28 @@ class VRDisplay final : public EventTargetWithInlineData,
using VRDisplayVector = HeapVector<Member<VRDisplay>>;
+// When adding values, insert them before Max and add them to
+// VRPresentationResult in enums.xml. Do not reuse values.
+// Also, remove kPlaceholderForPreviousHighValue.
+// When values become obsolete, comment them out here and mark them deprecated
+// in enums.xml.
enum class PresentationResult {
kRequested = 0,
kSuccess = 1,
kSuccessAlreadyPresenting = 2,
kVRDisplayCannotPresent = 3,
kPresentationNotSupportedByDisplay = 4,
- kVRDisplayNotFound = 5,
+ // kVRDisplayNotFound = 5,
kNotInitiatedByUserGesture = 6,
kInvalidNumberOfLayers = 7,
kInvalidLayerSource = 8,
kLayerSourceMissingWebGLContext = 9,
kInvalidLayerBounds = 10,
- kServiceInactive = 11,
- kRequestDenied = 12,
- kFullscreenNotEnabled = 13,
+ // kServiceInactive = 11,
+ // kRequestDenied = 12,
+ // kFullscreenNotEnabled = 13,
+ // TODO(ddorwin): Remove this placeholder when adding a new value.
+ kPlaceholderForPreviousHighValue = 13,
kPresentationResultMax, // Must be last member of enum.
};
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
index 23424fb8031..5f009fc2d9a 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
@@ -3,5 +3,6 @@ include_rules = [
"+services/device/public/mojom",
"+services/device/public/interfaces/constants.mojom-blink.h",
"+services/device/public/mojom/wake_lock.mojom-blink.h",
+ "+services/device/public/mojom/wake_lock_provider.mojom-blink.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
]
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
index 43671330e6c..58ea962fae5 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
@@ -27,11 +27,14 @@ ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
String lock_type) {
- // TODO(crbug.com/873030): Handle 'system' Wake Lock
if (lock_type == "screen") {
if (!wake_lock_screen_)
wake_lock_screen_ = WakeLock::CreateScreenWakeLock(script_state);
return wake_lock_screen_->GetPromise(script_state);
+ } else if (lock_type == "system") {
+ if (!wake_lock_system_)
+ wake_lock_system_ = WakeLock::CreateSystemWakeLock(script_state);
+ return wake_lock_system_->GetPromise(script_state);
}
return ScriptPromise::RejectWithDOMException(
@@ -51,6 +54,7 @@ NavigatorWakeLock& NavigatorWakeLock::From(Navigator& navigator) {
void NavigatorWakeLock::Trace(blink::Visitor* visitor) {
visitor->Trace(wake_lock_screen_);
+ visitor->Trace(wake_lock_system_);
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
index 1ffe09eee67..f6d0c183b9a 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
@@ -33,6 +33,7 @@ class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>,
explicit NavigatorWakeLock(Navigator&);
Member<WakeLock> wake_lock_screen_;
+ Member<WakeLock> wake_lock_system_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
index 109ce866f9f..f1947ebc4b5 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
@@ -5,12 +5,15 @@
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
#include "services/device/public/mojom/constants.mojom-blink.h"
+#include "services/device/public/mojom/wake_lock_provider.mojom-blink.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -20,14 +23,17 @@ WakeLock* WakeLock::CreateScreenWakeLock(ScriptState* script_state) {
return new WakeLock(script_state, LockType::kScreen);
}
+WakeLock* WakeLock::CreateSystemWakeLock(ScriptState* script_state) {
+ return new WakeLock(script_state, LockType::kSystem);
+}
+
WakeLock::~WakeLock() = default;
WakeLock::WakeLock(ScriptState* script_state, LockType type)
: ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
PageVisibilityObserver(
- ToDocument(blink::ExecutionContext::From(script_state))->GetPage()),
+ To<Document>(blink::ExecutionContext::From(script_state))->GetPage()),
type_(type) {
- DCHECK(type == LockType::kScreen);
}
ScriptPromise WakeLock::GetPromise(ScriptState* script_state) {
@@ -78,9 +84,23 @@ void WakeLock::BindToServiceIfNeeded() {
if (wake_lock_service_)
return;
- LocalFrame* frame = ToDocument(GetExecutionContext())->GetFrame();
- frame->GetInterfaceProvider().GetInterface(
+ device::mojom::blink::WakeLockType type;
+ switch (type_) {
+ case LockType::kSystem:
+ type = device::mojom::blink::WakeLockType::kPreventAppSuspension;
+ break;
+ case LockType::kScreen:
+ type = device::mojom::blink::WakeLockType::kPreventDisplaySleep;
+ break;
+ }
+
+ device::mojom::blink::WakeLockProviderPtr provider;
+ Platform::Current()->GetConnector()->BindInterface(
+ device::mojom::blink::kServiceName, mojo::MakeRequest(&provider));
+ provider->GetWakeLockWithoutContext(
+ type, device::mojom::blink::WakeLockReason::kOther, "Blink Wake Lock",
mojo::MakeRequest(&wake_lock_service_));
+
wake_lock_service_.set_connection_error_handler(
WTF::Bind(&WakeLock::OnConnectionError, WrapWeakPersistent(this)));
}
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
index 40112dc4acc..a8896f249de 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
@@ -36,6 +36,8 @@ class WakeLock final : public EventTargetWithInlineData,
// Called by NavigatorWakeLock to create Screen Wake Lock
static WakeLock* CreateScreenWakeLock(ScriptState*);
+ // Called by NavigatorWakeLock to create System Wake Lock
+ static WakeLock* CreateSystemWakeLock(ScriptState*);
// Resolves and returns same promise of that particular WakeLockType each time
ScriptPromise GetPromise(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
index 6a2819e3f18..39ee21aae4b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
@@ -35,7 +35,7 @@ namespace blink {
AnalyserHandler::AnalyserHandler(AudioNode& node, float sample_rate)
: AudioBasicInspectorHandler(kNodeTypeAnalyser, node, sample_rate, 1) {
- channel_count_ = 1;
+ channel_count_ = 2;
Initialize();
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc b/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc
index d5287d2b31a..aae1753fe87 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.cc
@@ -27,7 +27,6 @@
#include "base/location.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
@@ -35,6 +34,7 @@
#include "third_party/blink/renderer/platform/audio/audio_file_reader.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
namespace blink {
@@ -51,6 +51,10 @@ void AsyncAudioDecoder::DecodeAsync(
if (!audio_data)
return;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ context->GetExecutionContext()->GetTaskRunner(
+ blink::TaskType::kInternalMedia);
+
BackgroundScheduler::PostOnBackgroundThread(
FROM_HERE,
CrossThreadBind(&AsyncAudioDecoder::DecodeOnBackgroundThread,
@@ -58,7 +62,8 @@ void AsyncAudioDecoder::DecodeAsync(
WrapCrossThreadPersistent(success_callback),
WrapCrossThreadPersistent(error_callback),
WrapCrossThreadPersistent(resolver),
- WrapCrossThreadPersistent(context)));
+ WrapCrossThreadPersistent(context),
+ std::move(task_runner)));
}
void AsyncAudioDecoder::DecodeOnBackgroundThread(
@@ -67,7 +72,8 @@ void AsyncAudioDecoder::DecodeOnBackgroundThread(
V8PersistentCallbackFunction<V8DecodeSuccessCallback>* success_callback,
V8PersistentCallbackFunction<V8DecodeErrorCallback>* error_callback,
ScriptPromiseResolver* resolver,
- BaseAudioContext* context) {
+ BaseAudioContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
DCHECK(!IsMainThread());
scoped_refptr<AudioBus> bus = CreateBusFromInMemoryAudioFile(
audio_data->Data(), audio_data->ByteLength(), false, sample_rate);
@@ -80,7 +86,7 @@ void AsyncAudioDecoder::DecodeOnBackgroundThread(
// exist any more.
if (context) {
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner, FROM_HERE,
CrossThreadBind(&AsyncAudioDecoder::NotifyComplete,
WrapCrossThreadPersistent(audio_data),
WrapCrossThreadPersistent(success_callback),
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h b/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h
index 372849be732..5783e16946f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/async_audio_decoder.h
@@ -32,6 +32,10 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_decode_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_decode_success_callback.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
namespace blink {
class AudioBuffer;
@@ -71,7 +75,8 @@ class AsyncAudioDecoder {
V8PersistentCallbackFunction<V8DecodeSuccessCallback>*,
V8PersistentCallbackFunction<V8DecodeErrorCallback>*,
ScriptPromiseResolver*,
- BaseAudioContext*);
+ BaseAudioContext*,
+ scoped_refptr<base::SingleThreadTaskRunner>);
static void NotifyComplete(
DOMArrayBuffer* audio_data,
V8PersistentCallbackFunction<V8DecodeSuccessCallback>*,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
index 7e5d2d715cd..74ce5c17336 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
@@ -349,12 +349,20 @@ bool AudioBufferSourceHandler::RenderFromBuffer(
for (unsigned i = 0; i < number_of_channels; ++i) {
float* destination = destination_channels[i];
const float* source = source_channels[i];
-
- double sample1 = source[read_index];
- double sample2 = source[read_index2];
- double sample = (1.0 - interpolation_factor) * sample1 +
- interpolation_factor * sample2;
-
+ double sample;
+
+ if (read_index == read_index2 && read_index >= 1) {
+ // We're at the end of the buffer, so just linearly extrapolate from
+ // the last two samples.
+ double sample1 = source[read_index - 1];
+ double sample2 = source[read_index];
+ sample = sample2 + (sample2 - sample1) * interpolation_factor;
+ } else {
+ double sample1 = source[read_index];
+ double sample2 = source[read_index2];
+ sample = (1.0 - interpolation_factor) * sample1 +
+ interpolation_factor * sample2;
+ }
destination[write_index] = clampTo<float>(sample);
}
write_index++;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
index 272bb914556..9669d35a3f2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -14,13 +14,18 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/webaudio/audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_timestamp.h"
#include "third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h"
+#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h"
+#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
+#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -327,6 +332,32 @@ double AudioContext::baseLatency() const {
static_cast<double>(sampleRate());
}
+MediaElementAudioSourceNode* AudioContext::createMediaElementSource(
+ HTMLMediaElement* media_element,
+ ExceptionState& exception_state) {
+ DCHECK(IsMainThread());
+
+ return MediaElementAudioSourceNode::Create(*this, *media_element,
+ exception_state);
+}
+
+MediaStreamAudioSourceNode* AudioContext::createMediaStreamSource(
+ MediaStream* media_stream,
+ ExceptionState& exception_state) {
+ DCHECK(IsMainThread());
+
+ return MediaStreamAudioSourceNode::Create(*this, *media_stream,
+ exception_state);
+}
+
+MediaStreamAudioDestinationNode* AudioContext::createMediaStreamDestination(
+ ExceptionState& exception_state) {
+ DCHECK(IsMainThread());
+
+ // Set number of output channels to stereo by default.
+ return MediaStreamAudioDestinationNode::Create(*this, 2, exception_state);
+}
+
void AudioContext::NotifySourceNodeStart() {
source_node_started_ = true;
if (!user_gesture_required_)
@@ -361,13 +392,14 @@ AutoplayPolicy::Type AudioContext::GetAutoplayPolicy() const {
}
bool AudioContext::AreAutoplayRequirementsFulfilled() const {
+ DCHECK(GetDocument());
+
switch (GetAutoplayPolicy()) {
case AutoplayPolicy::Type::kNoUserGestureRequired:
return true;
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kUserGestureRequiredForCrossOrigin:
- return Frame::HasTransientUserActivation(
- GetDocument() ? GetDocument()->GetFrame() : nullptr);
+ return LocalFrame::HasTransientUserActivation(GetDocument()->GetFrame());
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
return AutoplayPolicy::IsDocumentAllowedToPlay(*GetDocument());
}
@@ -394,7 +426,7 @@ bool AudioContext::IsAllowedToStart() const {
if (!user_gesture_required_)
return true;
- Document* document = ToDocument(GetExecutionContext());
+ Document* document = To<Document>(GetExecutionContext());
DCHECK(document);
switch (GetAutoplayPolicy()) {
@@ -422,7 +454,7 @@ bool AudioContext::IsAllowedToStart() const {
}
void AudioContext::RecordAutoplayMetrics() {
- if (!autoplay_status_.has_value())
+ if (!autoplay_status_.has_value() || !GetDocument())
return;
ukm::UkmRecorder* ukm_recorder = GetDocument()->UkmRecorder();
@@ -494,7 +526,11 @@ void AudioContext::NotifyAudibleAudioStopped() {
DCHECK(IsMainThread());
DCHECK(audio_context_manager_);
- audio_context_manager_->AudioContextAudiblePlaybackStopped(context_id_);
+ // If we don't have a document, we don't need to notify anyone that we've
+ // stopped.
+ if (GetDocument()) {
+ audio_context_manager_->AudioContextAudiblePlaybackStopped(context_id_);
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
index d93934e4e0c..7a3db4c0c1b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -19,6 +19,11 @@ class AudioContextOptions;
class AudioTimestamp;
class Document;
class ExceptionState;
+class HTMLMediaElement;
+class MediaElementAudioSourceNode;
+class MediaStream;
+class MediaStreamAudioDestinationNode;
+class MediaStreamAudioSourceNode;
class ScriptState;
class WebAudioLatencyHint;
@@ -41,14 +46,21 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
ScriptPromise closeContext(ScriptState*);
bool IsContextClosed() const final;
- ScriptPromise suspendContext(ScriptState*) final;
- ScriptPromise resumeContext(ScriptState*) final;
+ ScriptPromise suspendContext(ScriptState*);
+ ScriptPromise resumeContext(ScriptState*);
bool HasRealtimeConstraint() final { return true; }
void getOutputTimestamp(ScriptState*, AudioTimestamp&);
double baseLatency() const;
+ MediaElementAudioSourceNode* createMediaElementSource(HTMLMediaElement*,
+ ExceptionState&);
+ MediaStreamAudioSourceNode* createMediaStreamSource(MediaStream*,
+ ExceptionState&);
+ MediaStreamAudioDestinationNode* createMediaStreamDestination(
+ ExceptionState&);
+
// Called by handlers of AudioScheduledSourceNode and AudioBufferSourceNode to
// notify their associated AudioContext when start() is called. It may resume
// the AudioContext if it is now allowed to start.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
index 2983635f315..e386af9d511 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
@@ -40,6 +40,7 @@ enum AudioContextLatencyCategory {
] interface AudioContext : BaseAudioContext {
[MeasureAs=AudioContextSuspend, CallWith=ScriptState, ImplementedAs=suspendContext] Promise<void> suspend();
[MeasureAs=AudioContextClose, CallWith=ScriptState, ImplementedAs=closeContext] Promise<void> close();
+ [MeasureAs=AudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
// Output timestamp
[MeasureAs=AudioContextGetOutputTimestamp, CallWith=ScriptState] AudioTimestamp getOutputTimestamp();
@@ -48,10 +49,8 @@ enum AudioContextLatencyCategory {
// passing the audio from the AudioDestinationNode to the audio subsystem
readonly attribute double baseLatency;
- // Sources
- // TODO(rtoy): The following methods should be here instead of in BaseAudioContext:
- //
- // createMediaElementSource(HTMLMediaElement mediaElement)
- // createMediaStreamSource(MediaStream mediaStream)
- // createMediaStreamDestination()
+ [RaisesException, MeasureAs=AudioContextCreateMediaElementSource] MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
+ [RaisesException, MeasureAs=AudioContextCreateMediaStreamSource] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
+ [RaisesException, MeasureAs=AudioContextCreateMediaStreamDestination] MediaStreamAudioDestinationNode createMediaStreamDestination();
+
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
index 93af83128ff..b9b40ca63c7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
@@ -84,11 +84,6 @@ class AudioContextAutoplayTestPlatform : public TestingPlatformSupport {
AudioHardwareSampleRate(), AudioHardwareBufferSize());
}
- std::unique_ptr<WebThread> CreateThread(
- const WebThreadCreationParams& params) override {
- return old_platform_->CreateThread(params);
- }
-
double AudioHardwareSampleRate() override { return 44100; }
size_t AudioHardwareBufferSize() override { return 128; }
};
@@ -264,8 +259,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeNoGesture_Main) {
// Creates an AudioContext with a user gesture inside a x-origin child frame.
TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateGesture_Child) {
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
AudioContext* audio_context = AudioContext::Create(
ChildDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
@@ -293,8 +288,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateGesture_Child) {
// Creates an AudioContext with a user gesture inside a main frame.
TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateGesture_Main) {
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(GetDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
AudioContext* audio_context = AudioContext::Create(
GetDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
@@ -325,8 +320,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Child) {
ChildDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
RejectPendingResolvers(audio_context);
@@ -360,8 +355,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Main) {
GetDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(GetDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
RejectPendingResolvers(audio_context);
@@ -440,8 +435,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartGesture_Child) {
ChildDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->NotifySourceNodeStart();
RecordAutoplayStatus(audio_context);
@@ -471,8 +466,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartGesture_Main) {
GetDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(GetDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->NotifySourceNodeStart();
RecordAutoplayStatus(audio_context);
@@ -503,8 +498,8 @@ TEST_P(AudioContextAutoplayTest,
audio_context->NotifySourceNodeStart();
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -539,8 +534,8 @@ TEST_P(AudioContextAutoplayTest,
audio_context->NotifySourceNodeStart();
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(GetDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -571,8 +566,8 @@ TEST_P(AudioContextAutoplayTest,
ChildDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->NotifySourceNodeStart();
audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
RejectPendingResolvers(audio_context);
@@ -607,8 +602,8 @@ TEST_P(AudioContextAutoplayTest,
GetDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
std::unique_ptr<UserGestureIndicator> user_gesture_scope =
- Frame::NotifyUserActivation(GetDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
audio_context->NotifySourceNodeStart();
audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
RejectPendingResolvers(audio_context);
@@ -634,8 +629,8 @@ TEST_P(AudioContextAutoplayTest,
// document previous received a user gesture.
TEST_P(AudioContextAutoplayTest,
AutoplayMetrics_DocumentReceivedGesture_Child) {
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
AudioContext* audio_context = AudioContext::Create(
ChildDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
@@ -671,8 +666,8 @@ TEST_P(AudioContextAutoplayTest,
// document previous received a user gesture.
TEST_P(AudioContextAutoplayTest,
AutoplayMetrics_DocumentReceivedGesture_Main) {
- Frame::NotifyUserActivation(ChildDocument().GetFrame(),
- UserGestureToken::kNewGesture);
+ LocalFrame::NotifyUserActivation(ChildDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
AudioContext* audio_context = AudioContext::Create(
GetDocument(), AudioContextOptions(), ASSERT_NO_EXCEPTION);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
index 6f994307305..2923f69a21f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
@@ -9,9 +9,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_audio_device.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
namespace blink {
@@ -72,11 +72,6 @@ class AudioContextTestPlatform : public TestingPlatformSupport {
AudioHardwareSampleRate(), buffer_size);
}
- std::unique_ptr<WebThread> CreateThread(
- const WebThreadCreationParams& params) override {
- return old_platform_->CreateThread(params);
- }
-
double AudioHardwareSampleRate() override { return 44100; }
size_t AudioHardwareBufferSize() override { return 128; }
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
index 936f36d5465..f3f1d0d78c2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -416,7 +416,7 @@ void AudioHandler::EnableOutputsIfNecessary() {
#if DEBUG_AUDIONODE_REFERENCES > 1
fprintf(stderr,
"[%16p]: %16p: %2d: EnableOutputsIfNecessary: is_disabled %d count "
- "%d output size %zu\n",
+ "%d output size %u\n",
Context(), this, GetNodeType(), is_disabled_, connection_ref_count_,
outputs_.size());
#endif
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
index eb6008313aa..24f4820c89b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -52,7 +52,9 @@ AudioParamHandler::AudioParamHandler(BaseAudioContext& context,
automation_rate_(rate),
rate_mode_(rate_mode),
min_value_(min_value),
- max_value_(max_value) {
+ max_value_(max_value),
+ summing_bus_(
+ AudioBus::Create(1, AudioUtilities::kRenderQuantumFrames, false)) {
// The destination MUST exist because we need the destination handler for the
// AudioParam.
CHECK(context.destination());
@@ -258,23 +260,25 @@ void AudioParamHandler::CalculateFinalValues(float* values,
SetIntrinsicValue(value);
}
- // Now sum all of the audio-rate connections together (unity-gain summing
- // junction). Note that connections would normally be mono, but we mix down
- // to mono if necessary.
- scoped_refptr<AudioBus> summing_bus =
- AudioBus::Create(1, number_of_values, false);
- summing_bus->SetChannelMemory(0, values, number_of_values);
+ // If there are any connections, sum all of the audio-rate connections
+ // together (unity-gain summing junction). Note that connections would
+ // normally be mono, but we mix down to mono if necessary.
+ if (NumberOfRenderingConnections() > 0) {
+ DCHECK_LE(number_of_values, AudioUtilities::kRenderQuantumFrames);
- for (unsigned i = 0; i < NumberOfRenderingConnections(); ++i) {
- AudioNodeOutput* output = RenderingOutput(i);
- DCHECK(output);
+ summing_bus_->SetChannelMemory(0, values, number_of_values);
- // Render audio from this output.
- AudioBus* connection_bus =
- output->Pull(nullptr, AudioUtilities::kRenderQuantumFrames);
+ for (unsigned i = 0; i < NumberOfRenderingConnections(); ++i) {
+ AudioNodeOutput* output = RenderingOutput(i);
+ DCHECK(output);
- // Sum, with unity-gain.
- summing_bus->SumFrom(*connection_bus);
+ // Render audio from this output.
+ AudioBus* connection_bus =
+ output->Pull(nullptr, AudioUtilities::kRenderQuantumFrames);
+
+ // Sum, with unity-gain.
+ summing_bus_->SumFrom(*connection_bus);
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
index 1dfb251c0a2..eca5b5875bd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
@@ -248,6 +248,9 @@ class AudioParamHandler final : public ThreadSafeRefCounted<AudioParamHandler>,
// The destination node used to get necessary information like the smaple rate
// and context time.
scoped_refptr<AudioDestinationHandler> destination_handler_;
+
+ // Audio bus to sum in any connections to the AudioParam.
+ scoped_refptr<AudioBus> summing_bus_;
};
// AudioParam class represents web-exposed AudioParam interface.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
index a7db4bac113..139b8c50bc2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
+#include "third_party/blink/renderer/platform/audio/vector_math.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/cpu.h"
@@ -551,12 +552,43 @@ void AudioParamTimeline::InsertEvent(std::unique_ptr<ParamEvent> event,
// Events of type |kSetValueCurveEnd| or |kCancelValues| never
// conflict.
if (!(test_type == ParamEvent::kSetValueCurveEnd ||
- test_type == ParamEvent::kCancelValues) &&
- events_[i]->Time() > event->Time() && events_[i]->Time() < end_time) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- EventToString(*event) + " overlaps " + EventToString(*events_[i]));
- return;
+ test_type == ParamEvent::kCancelValues)) {
+ if (test_type == ParamEvent::kSetValueCurve) {
+ // A SetValueCurve overlapping an existing SetValueCurve requires
+ // special care.
+ double test_end_time = events_[i]->Time() + events_[i]->Duration();
+ // Test if old event starts somewhere in the middle of the new event.
+ bool overlap = (events_[i]->Time() >= event->Time() &&
+ events_[i]->Time() < end_time);
+ // Test if old event ends somewhere in the middle of the new event.
+ overlap = overlap ||
+ (test_end_time > event->Time() && test_end_time < end_time);
+ // Test if new event starts somewhere in the middle of the old event.
+ overlap = overlap || (event->Time() >= events_[i]->Time() &&
+ event->Time() < test_end_time);
+ // Test if new event ends somewhere in the middle of the old event.
+ overlap = overlap || (end_time >= events_[i]->Time() &&
+ end_time < test_end_time);
+ if (overlap) {
+ // If the start time of the event overlaps the start/end of an
+ // existing event or if the existing event end overlaps the
+ // start/end of the event, it's an error.
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ EventToString(*event) + " overlaps " +
+ EventToString(*events_[i]));
+ return;
+ }
+ } else {
+ if (events_[i]->Time() > event->Time() &&
+ events_[i]->Time() < end_time) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ EventToString(*event) + " overlaps " +
+ EventToString(*events_[i]));
+ return;
+ }
+ }
}
} else {
// Otherwise, make sure this event doesn't overlap any existing
@@ -822,8 +854,8 @@ float AudioParamTimeline::ValuesForFrameRange(size_t start_frame,
number_of_values, sample_rate, control_rate);
// Clamp the values now to the nominal range
- for (unsigned k = 0; k < number_of_values; ++k)
- values[k] = clampTo(values[k], min_value, max_value);
+ VectorMath::Vclip(values, 1, &min_value, &max_value, values, 1,
+ number_of_values);
return last_value;
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
index a6fba8c4a19..761113d9ecd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
@@ -21,7 +21,8 @@ AudioWorklet* AudioWorklet::Create(BaseAudioContext* context) {
}
AudioWorklet::AudioWorklet(BaseAudioContext* context)
- : Worklet(ToDocument(context->GetExecutionContext())), context_(context) {}
+ : Worklet(To<Document>(context->GetExecutionContext())),
+ context_(context) {}
void AudioWorklet::CreateProcessor(
scoped_refptr<AudioWorkletHandler> handler,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
index 9dc2b84f96d..718ef75dbb8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
+#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h"
@@ -36,24 +37,23 @@ namespace blink {
AudioWorkletGlobalScope* AudioWorkletGlobalScope::Create(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
- v8::Isolate* isolate,
WorkerThread* thread) {
- return new AudioWorkletGlobalScope(std::move(creation_params), isolate,
- thread);
+ return new AudioWorkletGlobalScope(std::move(creation_params), thread);
}
AudioWorkletGlobalScope::AudioWorkletGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params,
- v8::Isolate* isolate,
WorkerThread* thread)
- : ThreadedWorkletGlobalScope(std::move(creation_params), isolate, thread) {}
+ : WorkletGlobalScope(std::move(creation_params),
+ thread->GetWorkerReportingProxy(),
+ thread) {}
AudioWorkletGlobalScope::~AudioWorkletGlobalScope() = default;
void AudioWorkletGlobalScope::Dispose() {
DCHECK(IsContextThread());
is_closing_ = true;
- ThreadedWorkletGlobalScope::Dispose();
+ WorkletGlobalScope::Dispose();
}
void AudioWorkletGlobalScope::registerProcessor(
@@ -401,7 +401,7 @@ double AudioWorkletGlobalScope::currentTime() const {
void AudioWorkletGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(processor_definition_map_);
visitor->Trace(processor_instances_);
- ThreadedWorkletGlobalScope::Trace(visitor);
+ WorkletGlobalScope::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
index d92c0055a41..ce29470c280 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/workers/threaded_worklet_global_scope.h"
+#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/platform/audio/audio_array.h"
@@ -46,14 +46,12 @@ class MODULES_EXPORT ProcessorCreationParams final {
// This is constructed and destroyed on a worker thread, and all methods also
// must be called on the worker thread.
-class MODULES_EXPORT AudioWorkletGlobalScope final
- : public ThreadedWorkletGlobalScope {
+class MODULES_EXPORT AudioWorkletGlobalScope final : public WorkletGlobalScope {
DEFINE_WRAPPERTYPEINFO();
public:
static AudioWorkletGlobalScope* Create(
std::unique_ptr<GlobalScopeCreationParams>,
- v8::Isolate*,
WorkerThread*);
~AudioWorkletGlobalScope() override;
bool IsAudioWorkletGlobalScope() const final { return true; }
@@ -106,7 +104,6 @@ class MODULES_EXPORT AudioWorkletGlobalScope final
private:
AudioWorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
- v8::Isolate*,
WorkerThread*);
bool is_closing_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
index d2130f08b8a..80b166f42dd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
@@ -55,7 +55,7 @@ static const size_t kRenderQuantumFrames = 128;
class AudioWorkletGlobalScopeTest : public PageTestBase {
public:
void SetUp() override {
- AudioWorkletThread::CreateSharedBackingThreadForTest();
+ AudioWorkletThread::EnsureSharedBackingThread();
PageTestBase::SetUp(IntSize());
Document* document = &GetDocument();
document->SetURL(KURL("https://example.com/"));
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
index d74292811d0..cee79bc7253 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -47,12 +47,15 @@ AudioWorkletHandler::AudioWorkletHandler(
AddInput();
}
- // If |options.outputChannelCount| unspecified, all outputs are mono.
+ if (options.hasOutputChannelCount()) {
+ is_output_channel_count_given_ = true;
+ }
+
for (unsigned i = 0; i < options.numberOfOutputs(); ++i) {
- unsigned long channel_count = options.hasOutputChannelCount()
+ // If |options.outputChannelCount| unspecified, all outputs are mono.
+ AddOutput(is_output_channel_count_given_
? options.outputChannelCount()[i]
- : 1;
- AddOutput(channel_count);
+ : 1);
}
if (Context()->GetExecutionContext()) {
@@ -132,9 +135,11 @@ void AudioWorkletHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
Context()->AssertGraphOwner();
DCHECK(input);
- // Dynamic channel count only works when the node has 1 input and 1 output.
- // Otherwise the channel count(s) should not be dynamically changed.
- if (NumberOfInputs() == 1 && NumberOfOutputs() == 1) {
+ // Dynamic channel count only works when the node has 1 input, 1 output and
+ // |outputChannelCount| is not given. Otherwise the channel count(s) should
+ // not be dynamically changed.
+ if (NumberOfInputs() == 1 && NumberOfOutputs() == 1 &&
+ !is_output_channel_count_given_) {
DCHECK_EQ(input, &this->Input(0));
unsigned number_of_input_channels = Input(0).NumberOfChannels();
if (number_of_input_channels != Output(0).NumberOfChannels()) {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
index be38e866031..058202c2392 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h
@@ -85,6 +85,9 @@ class AudioWorkletHandler final : public AudioHandler {
bool RequiresTailProcessing() const override { return true; }
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
+ // Used only if number of inputs and outputs are 1.
+ bool is_output_channel_count_given_ = false;
};
class AudioWorkletNode final : public AudioNode,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
index bf6104358df..2778e171275 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
@@ -52,28 +52,10 @@ WorkerBackingThread& AudioWorkletThread::GetWorkerBackingThread() {
return *WorkletThreadHolder<AudioWorkletThread>::GetInstance()->GetThread();
}
-void CollectAllGarbageOnAudioWorkletThread(WaitableEvent* done_event) {
- blink::ThreadState::Current()->CollectAllGarbage();
- done_event->Signal();
-}
-
-void AudioWorkletThread::CollectAllGarbage() {
- DCHECK(IsMainThread());
- WaitableEvent done_event;
- WorkletThreadHolder<AudioWorkletThread>* worklet_thread_holder =
- WorkletThreadHolder<AudioWorkletThread>::GetInstance();
- if (!worklet_thread_holder)
- return;
- worklet_thread_holder->GetThread()->BackingThread().PostTask(
- FROM_HERE, CrossThreadBind(&CollectAllGarbageOnAudioWorkletThread,
- CrossThreadUnretained(&done_event)));
- done_event.Wait();
-}
-
void AudioWorkletThread::EnsureSharedBackingThread() {
DCHECK(IsMainThread());
WorkletThreadHolder<AudioWorkletThread>::EnsureInstance(
- WebThreadCreationParams(blink::WebThreadType::kWebAudioThread));
+ ThreadCreationParams(WebThreadType::kWebAudioThread));
}
void AudioWorkletThread::ClearSharedBackingThread() {
@@ -82,24 +64,11 @@ void AudioWorkletThread::ClearSharedBackingThread() {
WorkletThreadHolder<AudioWorkletThread>::ClearInstance();
}
-WebThread* AudioWorkletThread::GetSharedBackingThread() {
- DCHECK(IsMainThread());
- WorkletThreadHolder<AudioWorkletThread>* instance =
- WorkletThreadHolder<AudioWorkletThread>::GetInstance();
- return &(instance->GetThread()->BackingThread().PlatformThread());
-}
-
-void AudioWorkletThread::CreateSharedBackingThreadForTest() {
- WorkletThreadHolder<AudioWorkletThread>::CreateForTest(
- WebThreadCreationParams(blink::WebThreadType::kWebAudioThread));
-}
-
WorkerOrWorkletGlobalScope* AudioWorkletThread::CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("audio-worklet"),
"AudioWorkletThread::createWorkerGlobalScope");
- return AudioWorkletGlobalScope::Create(std::move(creation_params),
- GetIsolate(), this);
+ return AudioWorkletGlobalScope::Create(std::move(creation_params), this);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
index 3181902f9c7..d3bf941fe3b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
@@ -28,19 +28,9 @@ class MODULES_EXPORT AudioWorkletThread final : public WorkerThread {
// The backing thread is cleared by clearSharedBackingThread().
void ClearWorkerBackingThread() override {}
- // This may block the main thread.
- static void CollectAllGarbage();
-
static void EnsureSharedBackingThread();
static void ClearSharedBackingThread();
- static void CreateSharedBackingThreadForTest();
-
- // This only can be called after EnsureSharedBackingThread() is performed.
- // Currently AudioWorkletThread owns only one thread and it is shared by all
- // the customers.
- static WebThread* GetSharedBackingThread();
-
private:
explicit AudioWorkletThread(WorkerReportingProxy&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
index 8c54cadf397..076dbbfff1b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
@@ -39,7 +39,7 @@ namespace blink {
class AudioWorkletThreadTest : public PageTestBase {
public:
void SetUp() override {
- AudioWorkletThread::CreateSharedBackingThreadForTest();
+ AudioWorkletThread::EnsureSharedBackingThread();
PageTestBase::SetUp(IntSize());
Document* document = &GetDocument();
document->SetURL(KURL("https://example.com/"));
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index 27cf8f0e928..64d9b51b82e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -33,10 +33,10 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/console_types.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/webaudio/analyser_node.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h"
@@ -56,9 +56,6 @@
#include "third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h"
#include "third_party/blink/renderer/modules/webaudio/gain_node.h"
#include "third_party/blink/renderer/modules/webaudio/iir_filter_node.h"
-#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h"
-#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
-#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h"
@@ -96,13 +93,15 @@ BaseAudioContext::BaseAudioContext(Document* document,
is_cleared_(false),
is_resolving_resume_promises_(false),
has_posted_cleanup_task_(false),
- deferred_task_handler_(DeferredTaskHandler::Create()),
+ deferred_task_handler_(DeferredTaskHandler::Create(
+ document->GetTaskRunner(TaskType::kInternalMedia))),
context_state_(kSuspended),
periodic_wave_sine_(nullptr),
periodic_wave_square_(nullptr),
periodic_wave_sawtooth_(nullptr),
periodic_wave_triangle_(nullptr),
- output_position_() {}
+ output_position_(),
+ task_runner_(document->GetTaskRunner(TaskType::kInternalMedia)) {}
BaseAudioContext::~BaseAudioContext() {
{
@@ -113,9 +112,6 @@ BaseAudioContext::~BaseAudioContext() {
}
GetDeferredTaskHandler().ContextWillBeDestroyed();
- DCHECK(!active_source_nodes_.size());
- DCHECK(!is_resolving_resume_promises_);
- DCHECK(!resume_resolvers_.size());
}
void BaseAudioContext::Initialize() {
@@ -173,6 +169,10 @@ void BaseAudioContext::Uninitialize() {
listener_->WaitForHRTFDatabaseLoaderThreadCompletion();
Clear();
+
+ DCHECK(!is_resolving_resume_promises_);
+ DCHECK_EQ(resume_resolvers_.size(), 0u);
+ DCHECK_EQ(active_source_nodes_.size(), 0u);
}
void BaseAudioContext::ContextDestroyed(ExecutionContext*) {
@@ -361,32 +361,6 @@ ConstantSourceNode* BaseAudioContext::createConstantSource(
return ConstantSourceNode::Create(*this, exception_state);
}
-MediaElementAudioSourceNode* BaseAudioContext::createMediaElementSource(
- HTMLMediaElement* media_element,
- ExceptionState& exception_state) {
- DCHECK(IsMainThread());
-
- return MediaElementAudioSourceNode::Create(*this, *media_element,
- exception_state);
-}
-
-MediaStreamAudioSourceNode* BaseAudioContext::createMediaStreamSource(
- MediaStream* media_stream,
- ExceptionState& exception_state) {
- DCHECK(IsMainThread());
-
- return MediaStreamAudioSourceNode::Create(*this, *media_stream,
- exception_state);
-}
-
-MediaStreamAudioDestinationNode* BaseAudioContext::createMediaStreamDestination(
- ExceptionState& exception_state) {
- DCHECK(IsMainThread());
-
- // Set number of output channels to stereo by default.
- return MediaStreamAudioDestinationNode::Create(*this, 2, exception_state);
-}
-
ScriptProcessorNode* BaseAudioContext::createScriptProcessor(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -632,7 +606,7 @@ void BaseAudioContext::SetContextState(AudioContextState new_state) {
if (was_audible_ && context_state_ != kRunning) {
was_audible_ = false;
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner_, FROM_HERE,
CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStopped,
WrapCrossThreadPersistent(this)));
}
@@ -660,7 +634,7 @@ void BaseAudioContext::NotifySourceNodeFinishedProcessing(
}
Document* BaseAudioContext::GetDocument() const {
- return ToDocument(GetExecutionContext());
+ return To<Document>(GetExecutionContext());
}
void BaseAudioContext::NotifySourceNodeStartedProcessing(AudioNode* node) {
@@ -762,12 +736,12 @@ void BaseAudioContext::HandlePostRenderTasks(const AudioBus* destination_bus) {
was_audible_ = is_audible;
if (is_audible) {
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner_, FROM_HERE,
CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStarted,
WrapCrossThreadPersistent(this)));
} else {
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner_, FROM_HERE,
CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStopped,
WrapCrossThreadPersistent(this)));
}
@@ -849,7 +823,7 @@ void BaseAudioContext::ScheduleMainThreadCleanup() {
if (has_posted_cleanup_task_)
return;
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner_, FROM_HERE,
CrossThreadBind(&BaseAudioContext::PerformCleanupOnMainThread,
WrapCrossThreadPersistent(this)));
has_posted_cleanup_task_ = true;
@@ -985,21 +959,4 @@ void BaseAudioContext::UpdateWorkletGlobalScopeOnRenderingThread() {
}
}
-bool BaseAudioContext::WouldTaintOrigin(const KURL& url) const {
- // Data URLs don't taint the origin.
- if (url.ProtocolIsData()) {
- return false;
- }
-
- Document* document = GetDocument();
- if (document && document->GetSecurityOrigin()) {
- // The origin is tainted if and only if we cannot read content from the URL.
- return !document->GetSecurityOrigin()->CanRequest(url);
- }
-
- // Be conservative and assume it's tainted if it's not a data url and if we
- // can't get the security origin of the document.
- return true;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
index fadb4834357..ae933f20167 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -49,6 +49,10 @@
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
namespace blink {
class AnalyserNode;
@@ -67,12 +71,7 @@ class Document;
class DynamicsCompressorNode;
class ExceptionState;
class GainNode;
-class HTMLMediaElement;
class IIRFilterNode;
-class MediaElementAudioSourceNode;
-class MediaStream;
-class MediaStreamAudioDestinationNode;
-class MediaStreamAudioSourceNode;
class OscillatorNode;
class PannerNode;
class PeriodicWave;
@@ -175,12 +174,6 @@ class MODULES_EXPORT BaseAudioContext
// JavaScript).
AudioBufferSourceNode* createBufferSource(ExceptionState&);
ConstantSourceNode* createConstantSource(ExceptionState&);
- MediaElementAudioSourceNode* createMediaElementSource(HTMLMediaElement*,
- ExceptionState&);
- MediaStreamAudioSourceNode* createMediaStreamSource(MediaStream*,
- ExceptionState&);
- MediaStreamAudioDestinationNode* createMediaStreamDestination(
- ExceptionState&);
GainNode* createGain(ExceptionState&);
BiquadFilterNode* createBiquadFilter(ExceptionState&);
WaveShaperNode* createWaveShaper(ExceptionState&);
@@ -216,12 +209,6 @@ class MODULES_EXPORT BaseAudioContext
const PeriodicWaveConstraints&,
ExceptionState&);
- // Suspend
- virtual ScriptPromise suspendContext(ScriptState*) = 0;
-
- // Resume
- virtual ScriptPromise resumeContext(ScriptState*) = 0;
-
// IIRFilter
IIRFilterNode* createIIRFilter(Vector<double> feedforward_coef,
Vector<double> feedback_coef,
@@ -309,13 +296,6 @@ class MODULES_EXPORT BaseAudioContext
// Does nothing when the worklet global scope does not exist.
void UpdateWorkletGlobalScopeOnRenderingThread();
- // Returns true if the URL would taint the origin so that we shouldn't be
- // allowing media to played through webaudio.
- // TODO(crbug.com/845913): This should really be on an AudioContext. Move
- // this when we move the media stuff from BaseAudioContext to AudioContext, as
- // requried by the spec.
- bool WouldTaintOrigin(const KURL& url) const;
-
protected:
enum ContextType { kRealtimeContext, kOfflineContext };
@@ -349,6 +329,16 @@ class MODULES_EXPORT BaseAudioContext
const String& Uuid() const { return uuid_; }
+ // The audio thread relies on the main thread to perform some operations
+ // over the objects that it owns and controls; |ScheduleMainThreadCleanup()|
+ // posts the task to initiate those.
+ void ScheduleMainThreadCleanup();
+
+ // Handles promise resolving, stopping and finishing up of audio source nodes
+ // etc. Actions that should happen, but can happen asynchronously to the
+ // audio thread making rendering progress.
+ void PerformCleanupOnMainThread();
+
private:
friend class AudioContextAutoplayTest;
@@ -388,18 +378,6 @@ class MODULES_EXPORT BaseAudioContext
// these Promises.
void ResolvePromisesForUnpause();
- // The audio thread relies on the main thread to perform some operations
- // over the objects that it owns and controls; |ScheduleMainThreadCleanup()|
- // posts the task to initiate those.
- //
- // That is, we combine all those sub-tasks into one task action for
- // convenience and performance, |PerformCleanupOnMainThread()|. It handles
- // promise resolving, stopping and finishing up of audio source nodes etc.
- // Actions that should happen, but can happen asynchronously to the
- // audio thread making rendering progress.
- void ScheduleMainThreadCleanup();
- void PerformCleanupOnMainThread();
-
// When the context is going away, reject any pending script promise
// resolvers.
virtual void RejectPendingResolvers();
@@ -466,6 +444,8 @@ class MODULES_EXPORT BaseAudioContext
// determine audibility on render quantum boundaries, so counting quanta is
// all that's needed.
size_t total_audible_renders_ = 0;
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
index 6bed5699721..a1d7cd614fb 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
@@ -61,15 +61,6 @@ callback DecodeSuccessCallback = void (AudioBuffer decodedData);
[RaisesException, MeasureAs=AudioContextCreateChannelSplitter] ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs);
[RaisesException, MeasureAs=AudioContextCreateChannelMerger] ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs);
- // Pause/resume
- [MeasureAs=AudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
-
- // TODO(rtoy): These really belong to the AudioContext, but we need them
- // here so we can use an offline audio context to test these.
- [RaisesException, MeasureAs=AudioContextCreateMediaElementSource] MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
- [RaisesException, MeasureAs=AudioContextCreateMediaStreamSource] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
- [RaisesException, MeasureAs=AudioContextCreateMediaStreamDestination] MediaStreamAudioDestinationNode createMediaStreamDestination();
-
[SecureContext] readonly attribute AudioWorklet audioWorklet;
attribute EventHandler onstatechange;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
index 372008bc98a..3e6b0b4f240 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
@@ -44,9 +44,7 @@ const size_t MaxFFTSize = 32768;
namespace blink {
ConvolverHandler::ConvolverHandler(AudioNode& node, float sample_rate)
- : AudioHandler(kNodeTypeConvolver, node, sample_rate),
- normalize_(true),
- buffer_has_been_set_(false) {
+ : AudioHandler(kNodeTypeConvolver, node, sample_rate), normalize_(true) {
AddInput();
AddOutput(1);
@@ -102,15 +100,6 @@ void ConvolverHandler::SetBuffer(AudioBuffer* buffer,
return;
}
- if (buffer && buffer_has_been_set_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "Cannot set buffer to non-null after it "
- "has been already been set to a non-null "
- "buffer");
- return;
- }
-
- buffer_has_been_set_ = true;
if (buffer->sampleRate() != Context()->sampleRate()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
index 16e71832ef9..fc11d61ce49 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h
@@ -31,6 +31,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
namespace blink {
@@ -85,10 +86,6 @@ class MODULES_EXPORT ConvolverHandler final : public AudioHandler {
// Normalize the impulse response or not. Must default to true.
bool normalize_;
- // True if the |buffer| attribute has ever been set to a non-null
- // value. Defaults to false.
- bool buffer_has_been_set_;
-
FRIEND_TEST_ALL_PREFIXES(ConvolverNodeTest, ReverbLifetime);
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h b/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
index 01f6c0d9eee..64cf12545be 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
@@ -14,7 +14,7 @@ namespace blink {
// when requested when the synchronization between AudioWorkletMessagingProxy
// and AudioWorkletGlobalScope.
class CrossThreadAudioParamInfo {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
explicit CrossThreadAudioParamInfo(const AudioParamDescriptor* descriptor)
@@ -39,7 +39,7 @@ class CrossThreadAudioParamInfo {
// created only when requested when the synchronization between
// AudioWorkletMessagingProxy and AudioWorkletGlobalScope.
class CrossThreadAudioWorkletProcessorInfo {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
explicit CrossThreadAudioWorkletProcessorInfo(
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
index 0e5675e2bd1..964e68ea31a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
@@ -68,21 +68,20 @@ void DefaultAudioDestinationHandler::Dispose() {
void DefaultAudioDestinationHandler::Initialize() {
DCHECK(IsMainThread());
- if (IsInitialized())
- return;
- CreateDestination();
+ CreatePlatformDestination();
AudioHandler::Initialize();
}
void DefaultAudioDestinationHandler::Uninitialize() {
DCHECK(IsMainThread());
- if (!IsInitialized())
- return;
- if (destination_->IsPlaying())
- StopDestination();
+ // It is possible that the handler is already uninitialized.
+ if (!IsInitialized()) {
+ return;
+ }
+ StopPlatformDestination();
AudioHandler::Uninitialize();
}
@@ -94,7 +93,7 @@ void DefaultAudioDestinationHandler::SetChannelCount(
// The channelCount for the input to this node controls the actual number of
// channels we send to the audio hardware. It can only be set if the number
// is less than the number of hardware channels.
- if (!MaxChannelCount() || channel_count > MaxChannelCount()) {
+ if (channel_count > MaxChannelCount()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kIndexSizeError,
ExceptionMessages::IndexOutsideRange<unsigned>(
@@ -108,33 +107,29 @@ void DefaultAudioDestinationHandler::SetChannelCount(
AudioHandler::SetChannelCount(channel_count, exception_state);
// Stop, re-create and start the destination to apply the new channel count.
- if (!exception_state.HadException() &&
- this->ChannelCount() != old_channel_count && IsInitialized()) {
- StopDestination();
- CreateDestination();
- StartDestination();
+ if (this->ChannelCount() != old_channel_count &&
+ !exception_state.HadException()) {
+ StopPlatformDestination();
+ CreatePlatformDestination();
+ StartPlatformDestination();
}
}
void DefaultAudioDestinationHandler::StartRendering() {
- DCHECK(IsInitialized());
- // Context might try to start rendering again while the destination is
- // running. Ignore it when that happens.
- if (IsInitialized() && !destination_->IsPlaying()) {
- StartDestination();
- }
+ DCHECK(IsMainThread());
+
+ StartPlatformDestination();
}
void DefaultAudioDestinationHandler::StopRendering() {
- DCHECK(IsInitialized());
- // Context might try to stop rendering again while the destination is stopped.
- // Ignore it when that happens.
- if (IsInitialized() && destination_->IsPlaying()) {
- StopDestination();
- }
+ DCHECK(IsMainThread());
+
+ StopPlatformDestination();
}
void DefaultAudioDestinationHandler::RestartRendering() {
+ DCHECK(IsMainThread());
+
StopRendering();
StartRendering();
}
@@ -144,7 +139,10 @@ unsigned long DefaultAudioDestinationHandler::MaxChannelCount() const {
}
double DefaultAudioDestinationHandler::SampleRate() const {
- return destination_ ? destination_->SampleRate() : 0;
+ // This can be accessed from both threads (main and audio), so it is
+ // possible that |platform_destination_| is not fully functional when it
+ // is accssed by the audio thread.
+ return platform_destination_ ? platform_destination_->SampleRate() : 0;
}
void DefaultAudioDestinationHandler::Render(
@@ -161,8 +159,9 @@ void DefaultAudioDestinationHandler::Render(
// safe execution of the subsequence operations because the hanlder holds
// the context as |UntracedMember| and it can go away anytime.
DCHECK(Context());
- if (!Context())
+ if (!Context()) {
return;
+ }
Context()->GetDeferredTaskHandler().SetAudioThreadToCurrentThread();
@@ -176,24 +175,23 @@ void DefaultAudioDestinationHandler::Render(
Context()->HandlePreRenderTasks(output_position);
- DCHECK_GE(NumberOfInputs(), 1u);
- if (NumberOfInputs() < 1) {
- destination_bus->Zero();
- return;
- }
-
// Renders the graph by pulling all the input(s) to this node. This will in
// turn pull on their input(s), all the way backwards through the graph.
AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames);
+ DCHECK(rendered_bus);
if (!rendered_bus) {
+ // AudioNodeInput might be in the middle of destruction. Then the internal
+ // summing bus will return as nullptr. Then zero out the output.
destination_bus->Zero();
} else if (rendered_bus != destination_bus) {
- // in-place processing was not possible - so copy
+ // In-place processing was not possible. Copy the rendererd result to the
+ // given |destination_bus| buffer.
destination_bus->CopyFrom(*rendered_bus);
}
- // Processes "automatic" nodes that are not connected to anything.
+ // Processes "automatic" nodes that are not connected to anything. This can
+ // be done after copying because it does not affect the rendered result.
Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes(
number_of_frames);
@@ -207,37 +205,46 @@ void DefaultAudioDestinationHandler::Render(
}
size_t DefaultAudioDestinationHandler::GetCallbackBufferSize() const {
- return destination_->CallbackBufferSize();
+ DCHECK(IsMainThread());
+ DCHECK(IsInitialized());
+
+ return platform_destination_->CallbackBufferSize();
}
int DefaultAudioDestinationHandler::GetFramesPerBuffer() const {
- return destination_ ? destination_->FramesPerBuffer() : 0;
+ DCHECK(IsMainThread());
+ DCHECK(IsInitialized());
+
+ return platform_destination_ ? platform_destination_->FramesPerBuffer() : 0;
}
-void DefaultAudioDestinationHandler::CreateDestination() {
- destination_ = AudioDestination::Create(*this, ChannelCount(), latency_hint_);
+void DefaultAudioDestinationHandler::CreatePlatformDestination() {
+ platform_destination_ =
+ AudioDestination::Create(*this, ChannelCount(), latency_hint_);
}
-void DefaultAudioDestinationHandler::StartDestination() {
- DCHECK(!destination_->IsPlaying());
+void DefaultAudioDestinationHandler::StartPlatformDestination() {
+ if (platform_destination_->IsPlaying()) {
+ return;
+ }
AudioWorklet* audio_worklet = Context()->audioWorklet();
if (audio_worklet && audio_worklet->IsReady()) {
// This task runner is only used to fire the audio render callback, so it
// MUST not be throttled to avoid potential audio glitch.
- destination_->StartWithWorkletTaskRunner(
+ platform_destination_->StartWithWorkletTaskRunner(
audio_worklet->GetMessagingProxy()
->GetBackingWorkerThread()
->GetTaskRunner(TaskType::kInternalMedia));
} else {
- destination_->Start();
+ platform_destination_->Start();
}
}
-void DefaultAudioDestinationHandler::StopDestination() {
- DCHECK(destination_->IsPlaying());
-
- destination_->Stop();
+void DefaultAudioDestinationHandler::StopPlatformDestination() {
+ if (platform_destination_->IsPlaying()) {
+ platform_destination_->Stop();
+ }
}
// -----------------------------------------------------------------------------
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h
index 65268abf8b7..0507a5a85ff 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.h
@@ -79,12 +79,14 @@ class DefaultAudioDestinationHandler final : public AudioDestinationHandler,
explicit DefaultAudioDestinationHandler(AudioNode&,
const WebAudioLatencyHint&);
- void CreateDestination();
- void StartDestination();
- void StopDestination();
+ void CreatePlatformDestination();
+ void StartPlatformDestination();
+ void StopPlatformDestination();
const WebAudioLatencyHint latency_hint_;
- scoped_refptr<AudioDestination> destination_;
+
+ // Holds the audio device thread that runs the real time audio context.
+ scoped_refptr<AudioDestination> platform_destination_;
};
// -----------------------------------------------------------------------------
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
index 70131fea333..073fbc01c0f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -26,11 +26,11 @@
#include "third_party/blink/renderer/modules/webaudio/deferred_task_handler.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
namespace blink {
@@ -127,38 +127,42 @@ void DeferredTaskHandler::HandleDirtyAudioNodeOutputs() {
output->UpdateRenderingState();
}
-void DeferredTaskHandler::AddAutomaticPullNode(AudioHandler* node) {
+void DeferredTaskHandler::AddAutomaticPullNode(
+ scoped_refptr<AudioHandler> node) {
AssertGraphOwner();
- if (!automatic_pull_nodes_.Contains(node)) {
- automatic_pull_nodes_.insert(node);
- automatic_pull_nodes_need_updating_ = true;
+ if (!automatic_pull_handlers_.Contains(node)) {
+ automatic_pull_handlers_.insert(node);
+ automatic_pull_handlers_need_updating_ = true;
}
}
-void DeferredTaskHandler::RemoveAutomaticPullNode(AudioHandler* node) {
+void DeferredTaskHandler::RemoveAutomaticPullNode(
+ scoped_refptr<AudioHandler> node) {
AssertGraphOwner();
- if (automatic_pull_nodes_.Contains(node)) {
- automatic_pull_nodes_.erase(node);
- automatic_pull_nodes_need_updating_ = true;
+ if (automatic_pull_handlers_.Contains(node)) {
+ automatic_pull_handlers_.erase(node);
+ automatic_pull_handlers_need_updating_ = true;
}
}
void DeferredTaskHandler::UpdateAutomaticPullNodes() {
AssertGraphOwner();
- if (automatic_pull_nodes_need_updating_) {
- CopyToVector(automatic_pull_nodes_, rendering_automatic_pull_nodes_);
- automatic_pull_nodes_need_updating_ = false;
+ if (automatic_pull_handlers_need_updating_) {
+ CopyToVector(automatic_pull_handlers_, rendering_automatic_pull_handlers_);
+ automatic_pull_handlers_need_updating_ = false;
}
}
void DeferredTaskHandler::ProcessAutomaticPullNodes(size_t frames_to_process) {
DCHECK(IsAudioThread());
- for (unsigned i = 0; i < rendering_automatic_pull_nodes_.size(); ++i)
- rendering_automatic_pull_nodes_[i]->ProcessIfNecessary(frames_to_process);
+ for (unsigned i = 0; i < rendering_automatic_pull_handlers_.size(); ++i) {
+ rendering_automatic_pull_handlers_[i]->ProcessIfNecessary(
+ frames_to_process);
+ }
}
void DeferredTaskHandler::AddTailProcessingHandler(
@@ -261,19 +265,18 @@ void DeferredTaskHandler::UpdateChangedChannelInterpretation() {
deferred_channel_interpretation_change_.clear();
}
-DeferredTaskHandler::DeferredTaskHandler()
- : automatic_pull_nodes_need_updating_(false), audio_thread_(0) {}
+DeferredTaskHandler::DeferredTaskHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : automatic_pull_handlers_need_updating_(false),
+ task_runner_(std::move(task_runner)),
+ audio_thread_(0) {}
-scoped_refptr<DeferredTaskHandler> DeferredTaskHandler::Create() {
- return base::AdoptRef(new DeferredTaskHandler());
+scoped_refptr<DeferredTaskHandler> DeferredTaskHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ return base::AdoptRef(new DeferredTaskHandler(std::move(task_runner)));
}
-DeferredTaskHandler::~DeferredTaskHandler() {
- DCHECK(!automatic_pull_nodes_.size());
- if (automatic_pull_nodes_need_updating_)
- rendering_automatic_pull_nodes_.resize(automatic_pull_nodes_.size());
- DCHECK(!rendering_automatic_pull_nodes_.size());
-}
+DeferredTaskHandler::~DeferredTaskHandler() = default;
void DeferredTaskHandler::HandleDeferredTasks() {
UpdateChangedChannelCountMode();
@@ -319,7 +322,7 @@ void DeferredTaskHandler::RequestToDeleteHandlersOnMainThread() {
deletable_orphan_handlers_.AppendVector(rendering_orphan_handlers_);
rendering_orphan_handlers_.clear();
PostCrossThreadTask(
- *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ *task_runner_, FROM_HERE,
CrossThreadBind(&DeferredTaskHandler::DeleteHandlersOnMainThread,
scoped_refptr<DeferredTaskHandler>(this)));
}
@@ -337,6 +340,8 @@ void DeferredTaskHandler::ClearHandlersToBeDeleted() {
tail_processing_handlers_.clear();
rendering_orphan_handlers_.clear();
deletable_orphan_handlers_.clear();
+ automatic_pull_handlers_.clear();
+ rendering_automatic_pull_handlers_.clear();
}
void DeferredTaskHandler::SetAudioThreadToCurrentThread() {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
index f83258f9793..aa1752797db 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
@@ -35,6 +35,10 @@
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
namespace blink {
class BaseAudioContext;
@@ -59,7 +63,8 @@ class AudioSummingJunction;
class MODULES_EXPORT DeferredTaskHandler final
: public ThreadSafeRefCounted<DeferredTaskHandler> {
public:
- static scoped_refptr<DeferredTaskHandler> Create();
+ static scoped_refptr<DeferredTaskHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~DeferredTaskHandler();
void HandleDeferredTasks();
@@ -69,8 +74,9 @@ class MODULES_EXPORT DeferredTaskHandler final
// when they are not connected to any downstream nodes. These two methods are
// called by the nodes who want to add/remove themselves into/from the
// automatic pull lists.
- void AddAutomaticPullNode(AudioHandler*);
- void RemoveAutomaticPullNode(AudioHandler*);
+ void AddAutomaticPullNode(scoped_refptr<AudioHandler>);
+ void RemoveAutomaticPullNode(scoped_refptr<AudioHandler>);
+
// Called right before handlePostRenderTasks() to handle nodes which need to
// be pulled even when they are not connected to anything.
void ProcessAutomaticPullNodes(size_t frames_to_process);
@@ -180,7 +186,7 @@ class MODULES_EXPORT DeferredTaskHandler final
};
private:
- DeferredTaskHandler();
+ explicit DeferredTaskHandler(scoped_refptr<base::SingleThreadTaskRunner>);
void UpdateAutomaticPullNodes();
void UpdateChangedChannelCountMode();
void UpdateChangedChannelInterpretation();
@@ -192,15 +198,16 @@ class MODULES_EXPORT DeferredTaskHandler final
// has been processed.
void UpdateTailProcessingHandlers();
- // For the sake of thread safety, we maintain a seperate Vector of automatic
- // pull nodes for rendering in m_renderingAutomaticPullNodes. It will be
- // copied from m_automaticPullNodes by updateAutomaticPullNodes() at the
- // very start or end of the rendering quantum.
- HashSet<AudioHandler*> automatic_pull_nodes_;
- Vector<AudioHandler*> rendering_automatic_pull_nodes_;
- // m_automaticPullNodesNeedUpdating keeps track if m_automaticPullNodes is
- // modified.
- bool automatic_pull_nodes_need_updating_;
+ // For the sake of thread safety, we maintain a seperate Vector of
+ // AudioHandlers for "automatic-pull nodes":
+ // |rendering_automatic_pull_handlers|. This storage will be copied from
+ // |automatic_pull_handlers| by |UpdateAutomaticPullNodes()| at the beginning
+ // or end of the render quantum.
+ HashSet<scoped_refptr<AudioHandler>> automatic_pull_handlers_;
+ Vector<scoped_refptr<AudioHandler>> rendering_automatic_pull_handlers_;
+
+ // Keeps track if the |automatic_pull_handlers| storage is touched.
+ bool automatic_pull_handlers_need_updating_;
// Collection of nodes where the channel count mode has changed. We want the
// channel count mode to change in the pre- or post-rendering phase so as
@@ -227,6 +234,8 @@ class MODULES_EXPORT DeferredTaskHandler final
// main thread will disable the outputs.
Vector<scoped_refptr<AudioHandler>> finished_tail_processing_handlers_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
// Graph locking.
RecursiveMutex context_graph_mutex_;
volatile ThreadIdentifier audio_thread_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
index 9c24f3a4ff5..d7b07b5fea7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
@@ -29,8 +29,8 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_options.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -136,19 +136,7 @@ void MediaElementAudioSourceHandler::SetFormat(size_t number_of_channels,
}
bool MediaElementAudioSourceHandler::WouldTaintOrigin() {
- // If we're cross-origin and allowed access vie CORS, we're not tainted.
- if (MediaElement()->GetWebMediaPlayer()->DidPassCORSAccessCheck()) {
- return false;
- }
-
- // Handles the case where the url is a redirect to another site that we're not
- // allowed to access.
- if (!MediaElement()->HasSingleSecurityOrigin()) {
- return true;
- }
-
- // Test to see if the current media URL taint the origin of the audio context?
- return Context()->WouldTaintOrigin(MediaElement()->currentSrc());
+ return MediaElement()->GetWebMediaPlayer()->WouldTaintOrigin();
}
void MediaElementAudioSourceHandler::PrintCORSMessage(const String& message) {
@@ -217,14 +205,14 @@ void MediaElementAudioSourceHandler::unlock() {
// ----------------------------------------------------------------
MediaElementAudioSourceNode::MediaElementAudioSourceNode(
- BaseAudioContext& context,
+ AudioContext& context,
HTMLMediaElement& media_element)
: AudioNode(context) {
SetHandler(MediaElementAudioSourceHandler::Create(*this, media_element));
}
MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create(
- BaseAudioContext& context,
+ AudioContext& context,
HTMLMediaElement& media_element,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -261,7 +249,7 @@ MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create(
}
MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create(
- BaseAudioContext* context,
+ AudioContext* context,
const MediaElementAudioSourceOptions& options,
ExceptionState& exception_state) {
return Create(*context, *options.mediaElement(), exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
index 311d563cebb..9fbb8127720 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h
@@ -33,11 +33,12 @@
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/platform/audio/audio_source_provider_client.h"
#include "third_party/blink/renderer/platform/audio/multi_channel_resampler.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
namespace blink {
-class BaseAudioContext;
+class AudioContext;
class HTMLMediaElement;
class MediaElementAudioSourceOptions;
@@ -114,13 +115,11 @@ class MediaElementAudioSourceNode final : public AudioNode,
USING_GARBAGE_COLLECTED_MIXIN(MediaElementAudioSourceNode);
public:
- static MediaElementAudioSourceNode* Create(BaseAudioContext&,
+ static MediaElementAudioSourceNode* Create(AudioContext&,
HTMLMediaElement&,
ExceptionState&);
- static MediaElementAudioSourceNode* Create(
- BaseAudioContext*,
- const MediaElementAudioSourceOptions&,
- ExceptionState&);
+ static MediaElementAudioSourceNode*
+ Create(AudioContext*, const MediaElementAudioSourceOptions&, ExceptionState&);
void Trace(blink::Visitor*) override;
MediaElementAudioSourceHandler& GetMediaElementAudioSourceHandler() const;
@@ -135,7 +134,7 @@ class MediaElementAudioSourceNode final : public AudioNode,
UNLOCK_FUNCTION(GetMediaElementAudioSourceHandler().GetProcessLock());
private:
- MediaElementAudioSourceNode(BaseAudioContext&, HTMLMediaElement&);
+ MediaElementAudioSourceNode(AudioContext&, HTMLMediaElement&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
index 8a1df10e151..991626190db 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
@@ -25,8 +25,7 @@
// See https://webaudio.github.io/web-audio-api/#mediaelementaudiosourcenode
[
- // TODO(rtoy): This should be AudioContext, not BaseAudioContext.
- Constructor(BaseAudioContext context, MediaElementAudioSourceOptions options),
+ Constructor(AudioContext context, MediaElementAudioSourceOptions options),
RaisesException=Constructor,
Measure
]
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
index d9f697bf68a..31f983cea2b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc
@@ -26,7 +26,7 @@
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
-#include "third_party/blink/renderer/core/frame/deprecation.h"
+#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
@@ -142,7 +142,7 @@ unsigned long MediaStreamAudioDestinationHandler::MaxChannelCount() const {
// ----------------------------------------------------------------
MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(
- BaseAudioContext& context,
+ AudioContext& context,
size_t number_of_channels)
: AudioBasicInspectorNode(context) {
SetHandler(
@@ -150,7 +150,7 @@ MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(
}
MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
- BaseAudioContext& context,
+ AudioContext& context,
size_t number_of_channels,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -164,7 +164,7 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
}
MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
- BaseAudioContext* context,
+ AudioContext* context,
const AudioNodeOptions& options,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -182,12 +182,6 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
node->HandleChannelOptions(options, exception_state);
- if (!context->HasRealtimeConstraint()) {
- Deprecation::CountDeprecation(
- node->GetExecutionContext(),
- WebFeature::kMediaStreamDestinationOnOfflineContext);
- }
-
return node;
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
index b4a5710cbc5..427d924d5d4 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h
@@ -33,7 +33,7 @@
namespace blink {
-class BaseAudioContext;
+class AudioContext;
class MediaStreamAudioDestinationHandler final
: public AudioBasicInspectorHandler {
@@ -78,17 +78,17 @@ class MediaStreamAudioDestinationNode final : public AudioBasicInspectorNode {
DEFINE_WRAPPERTYPEINFO();
public:
- static MediaStreamAudioDestinationNode* Create(BaseAudioContext&,
+ static MediaStreamAudioDestinationNode* Create(AudioContext&,
size_t number_of_channels,
ExceptionState&);
- static MediaStreamAudioDestinationNode* Create(BaseAudioContext*,
+ static MediaStreamAudioDestinationNode* Create(AudioContext*,
const AudioNodeOptions&,
ExceptionState&);
MediaStream* stream() const;
private:
- MediaStreamAudioDestinationNode(BaseAudioContext&, size_t number_of_channels);
+ MediaStreamAudioDestinationNode(AudioContext&, size_t number_of_channels);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
index 7cc91d87cc3..d4bc924b9a1 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
@@ -25,7 +25,7 @@
// See https://webaudio.github.io/web-audio-api/#mediastreamaudiodestinationnode
[
- Constructor(BaseAudioContext context, optional AudioNodeOptions options),
+ Constructor(AudioContext context, optional AudioNodeOptions options),
RaisesException=Constructor,
Measure
]
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
index 59c845c491f..488a5380262 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
@@ -26,9 +26,8 @@
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
#include <memory>
-#include "third_party/blink/renderer/core/frame/deprecation.h"
+#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/locker.h"
@@ -120,7 +119,7 @@ void MediaStreamAudioSourceHandler::Process(size_t number_of_frames) {
// ----------------------------------------------------------------
MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(
- BaseAudioContext& context,
+ AudioContext& context,
MediaStream& media_stream,
MediaStreamTrack* audio_track,
std::unique_ptr<AudioSourceProvider> audio_source_provider)
@@ -132,7 +131,7 @@ MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(
}
MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
- BaseAudioContext& context,
+ AudioContext& context,
MediaStream& media_stream,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -166,17 +165,11 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
// context keeps reference until node is disconnected
context.NotifySourceNodeStartedProcessing(node);
- if (!context.HasRealtimeConstraint()) {
- Deprecation::CountDeprecation(
- node->GetExecutionContext(),
- WebFeature::kMediaStreamSourceOnOfflineContext);
- }
-
return node;
}
MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
- BaseAudioContext* context,
+ AudioContext* context,
const MediaStreamAudioSourceOptions& options,
ExceptionState& exception_state) {
return Create(*context, *options.mediaStream(), exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
index f903710cba2..21bd3e48818 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h
@@ -36,7 +36,7 @@
namespace blink {
-class BaseAudioContext;
+class AudioContext;
class MediaStreamAudioSourceOptions;
class MediaStreamAudioSourceHandler final : public AudioHandler {
@@ -83,13 +83,11 @@ class MediaStreamAudioSourceNode final : public AudioNode,
USING_GARBAGE_COLLECTED_MIXIN(MediaStreamAudioSourceNode);
public:
- static MediaStreamAudioSourceNode* Create(BaseAudioContext&,
+ static MediaStreamAudioSourceNode* Create(AudioContext&,
MediaStream&,
ExceptionState&);
- static MediaStreamAudioSourceNode* Create(
- BaseAudioContext*,
- const MediaStreamAudioSourceOptions&,
- ExceptionState&);
+ static MediaStreamAudioSourceNode*
+ Create(AudioContext*, const MediaStreamAudioSourceOptions&, ExceptionState&);
void Trace(blink::Visitor*) override;
@@ -99,7 +97,7 @@ class MediaStreamAudioSourceNode final : public AudioNode,
void SetFormat(size_t number_of_channels, float sample_rate) override;
private:
- MediaStreamAudioSourceNode(BaseAudioContext&,
+ MediaStreamAudioSourceNode(AudioContext&,
MediaStream&,
MediaStreamTrack*,
std::unique_ptr<AudioSourceProvider>);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
index 1e8713dd726..e3c8a6c05be 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
@@ -25,7 +25,7 @@
// See https://webaudio.github.io/web-audio-api/#mediastreamaudiosourcenode
[
- Constructor(BaseAudioContext context, MediaStreamAudioSourceOptions options),
+ Constructor(AudioContext context, MediaStreamAudioSourceOptions options),
RaisesException=Constructor,
Measure
]
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
index fa3c1d6dc0b..ba5601767ff 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc
@@ -50,14 +50,13 @@ OfflineAudioContext* OfflineAudioContext::Create(
float sample_rate,
ExceptionState& exception_state) {
// FIXME: add support for workers.
- if (!context || !context->IsDocument()) {
+ auto* document = DynamicTo<Document>(context);
+ if (!document) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Workers are not supported.");
return nullptr;
}
- Document* document = ToDocument(context);
-
if (!number_of_frames) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
@@ -222,12 +221,6 @@ ScriptPromise OfflineAudioContext::startOfflineRendering(
return complete_resolver_->Promise();
}
-ScriptPromise OfflineAudioContext::suspendContext(ScriptState* script_state) {
- LOG(FATAL) << "This CANNOT be called on OfflineAudioContext; this is only to "
- "implement the pure virtual interface from BaseAudioContext.";
- return ScriptPromise();
-}
-
ScriptPromise OfflineAudioContext::suspendContext(ScriptState* script_state,
double when) {
DCHECK(IsMainThread());
@@ -379,6 +372,8 @@ void OfflineAudioContext::FireCompletionEvent() {
}
is_rendering_started_ = false;
+
+ PerformCleanupOnMainThread();
}
bool OfflineAudioContext::HandlePreOfflineRenderTasks() {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
index dc9e3bddb19..17e47893dc1 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h
@@ -59,11 +59,7 @@ class MODULES_EXPORT OfflineAudioContext final : public BaseAudioContext {
ScriptPromise startOfflineRendering(ScriptState*);
ScriptPromise suspendContext(ScriptState*, double);
- ScriptPromise resumeContext(ScriptState*) final;
-
- // This is to implement the pure virtual method from BaseAudioContext.
- // CANNOT be called from an OfflineAudioContext.
- ScriptPromise suspendContext(ScriptState*) final;
+ ScriptPromise resumeContext(ScriptState*);
void RejectPendingResolvers() override;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
index 92d713de756..3c57739a7da 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
@@ -36,4 +36,5 @@
readonly attribute unsigned long length;
[CallWith=ScriptState, ImplementedAs=startOfflineRendering, MeasureAs=OfflineAudioContextStartRendering] Promise<AudioBuffer> startRendering();
[CallWith=ScriptState, ImplementedAs=suspendContext, MeasureAs=OfflineAudioContextSuspend] Promise<void> suspend(double suspendTime);
+ [MeasureAs=OfflineAudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
index 673121b3094..fd5e12d5934 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
@@ -373,7 +373,7 @@ void OfflineAudioDestinationHandler::PrepareTaskRunnerForRendering() {
if (!render_thread_) {
// The context started from the non-AudioWorklet mode.
render_thread_ = Platform::Current()->CreateThread(
- WebThreadCreationParams(WebThreadType::kOfflineAudioRenderThread));
+ ThreadCreationParams(WebThreadType::kOfflineAudioRenderThread));
render_thread_task_runner_ = render_thread_->GetTaskRunner();
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
index db4a535ab41..dc658d2a2f7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h
@@ -28,10 +28,10 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_destination_node.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
namespace blink {
@@ -145,7 +145,7 @@ class OfflineAudioDestinationHandler final : public AudioDestinationHandler {
// The rendering thread for the non-AudioWorklet mode. For the AudioWorklet
// node, AudioWorkletThread will drive the rendering.
- std::unique_ptr<WebThread> render_thread_;
+ std::unique_ptr<Thread> render_thread_;
scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
index 6292f04046f..c1f07b9f888 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -154,6 +154,28 @@ bool OscillatorHandler::SetType(unsigned type) {
return true;
}
+// Convert the detune value (in cents) to a frequency scale multiplier:
+// 2^(d/1200)
+static float DetuneToFrequencyMultiplier(float detune_value) {
+ return std::exp2(detune_value / 1200);
+}
+
+// Clamp the frequency value to lie with Nyquist frequency. For NaN, arbitrarily
+// clamp to +Nyquist.
+static void ClampFrequency(float* frequency,
+ int frames_to_process,
+ float nyquist) {
+ for (int k = 0; k < frames_to_process; ++k) {
+ float f = frequency[k];
+
+ if (std::isnan(f)) {
+ frequency[k] = nyquist;
+ } else {
+ frequency[k] = clampTo(f, -nyquist, nyquist);
+ }
+ }
+}
+
bool OscillatorHandler::CalculateSampleAccuratePhaseIncrements(
size_t frames_to_process) {
bool is_good = frames_to_process <= phase_increments_.size() &&
@@ -199,9 +221,9 @@ bool OscillatorHandler::CalculateSampleAccuratePhaseIncrements(
// Convert from cents to rate scalar.
float k = 1.0 / 1200;
Vsmul(detune_values, 1, &k, detune_values, 1, frames_to_process);
- for (unsigned i = 0; i < frames_to_process; ++i)
- detune_values[i] = powf(
- 2, detune_values[i]); // FIXME: converting to expf() will be faster.
+ for (unsigned i = 0; i < frames_to_process; ++i) {
+ detune_values[i] = std::exp2(detune_values[i]);
+ }
if (has_frequency_changes) {
// Multiply frequencies by detune scalings.
@@ -212,11 +234,13 @@ bool OscillatorHandler::CalculateSampleAccuratePhaseIncrements(
// Handle ordinary parameter changes if there are no scheduled
// changes.
float detune = detune_->Value();
- float detune_scale = powf(2, detune / 1200);
+ float detune_scale = DetuneToFrequencyMultiplier(detune);
final_scale *= detune_scale;
}
if (has_sample_accurate_values) {
+ ClampFrequency(phase_increments, frames_to_process,
+ Context()->sampleRate() / 2);
// Convert from frequency to wavetable increment.
Vsmul(phase_increments, 1, &final_scale, phase_increments, 1,
frames_to_process);
@@ -232,6 +256,7 @@ static float DoInterpolation(double virtual_read_index,
const float* lower_wave_data,
const float* higher_wave_data) {
DCHECK_GE(incr, 0);
+ DCHECK(std::isfinite(virtual_read_index));
double sample_lower = 0;
double sample_higher = 0;
@@ -392,8 +417,9 @@ void OscillatorHandler::Process(size_t frames_to_process) {
if (!has_sample_accurate_values) {
frequency = frequency_->Value();
float detune = detune_->Value();
- float detune_scale = powf(2, detune / 1200);
+ float detune_scale = DetuneToFrequencyMultiplier(detune);
frequency *= detune_scale;
+ ClampFrequency(&frequency, 1, Context()->sampleRate() / 2);
periodic_wave_->WaveDataForFundamentalFrequency(frequency, lower_wave_data,
higher_wave_data,
table_interpolation_factor);
@@ -479,12 +505,14 @@ OscillatorNode::OscillatorNode(BaseAudioContext& context,
-context.sampleRate() / 2,
context.sampleRate() / 2)),
// Default to no detuning.
- detune_(AudioParam::Create(
- context,
- kParamTypeOscillatorDetune,
- 0,
- AudioParamHandler::AutomationRate::kAudio,
- AudioParamHandler::AutomationRateMode::kVariable)) {
+ detune_(
+ AudioParam::Create(context,
+ kParamTypeOscillatorDetune,
+ 0,
+ AudioParamHandler::AutomationRate::kAudio,
+ AudioParamHandler::AutomationRateMode::kVariable,
+ -1200 * log2f(std::numeric_limits<float>::max()),
+ 1200 * log2f(std::numeric_limits<float>::max()))) {
SetHandler(OscillatorHandler::Create(
*this, context.sampleRate(), oscillator_type, wave_table,
frequency_->Handler(), detune_->Handler()));
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
index 51821b017fa..fac20df4477 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -740,10 +740,10 @@ PannerNode* PannerNode::Create(BaseAudioContext* context,
node->setRefDistance(options.refDistance(), exception_state);
node->setMaxDistance(options.maxDistance(), exception_state);
- node->setRolloffFactor(options.rolloffFactor());
+ node->setRolloffFactor(options.rolloffFactor(), exception_state);
node->setConeInnerAngle(options.coneInnerAngle());
node->setConeOuterAngle(options.coneOuterAngle());
- node->setConeOuterGain(options.coneOuterGain());
+ node->setConeOuterGain(options.coneOuterGain(), exception_state);
return node;
}
@@ -818,7 +818,15 @@ double PannerNode::rolloffFactor() const {
return GetPannerHandler().RolloffFactor();
}
-void PannerNode::setRolloffFactor(double factor) {
+void PannerNode::setRolloffFactor(double factor,
+ ExceptionState& exception_state) {
+ if (factor < 0) {
+ exception_state.ThrowRangeError(
+ ExceptionMessages::IndexExceedsMinimumBound<double>("rolloffFactor",
+ factor, 0));
+ return;
+ }
+
GetPannerHandler().SetRolloffFactor(factor);
}
@@ -842,7 +850,17 @@ double PannerNode::coneOuterGain() const {
return GetPannerHandler().ConeOuterGain();
}
-void PannerNode::setConeOuterGain(double gain) {
+void PannerNode::setConeOuterGain(double gain,
+ ExceptionState& exception_state) {
+ if (gain < 0 || gain > 1) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ ExceptionMessages::IndexOutsideRange<double>(
+ "coneOuterGain", gain, 0, ExceptionMessages::kInclusiveBound, 1,
+ ExceptionMessages::kInclusiveBound));
+ return;
+ }
+
GetPannerHandler().SetConeOuterGain(gain);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
index b1f2896d3f9..2e4851c6c7a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
@@ -236,13 +236,13 @@ class PannerNode final : public AudioNode {
double maxDistance() const;
void setMaxDistance(double, ExceptionState&);
double rolloffFactor() const;
- void setRolloffFactor(double);
+ void setRolloffFactor(double, ExceptionState&);
double coneInnerAngle() const;
void setConeInnerAngle(double);
double coneOuterAngle() const;
void setConeOuterAngle(double);
double coneOuterGain() const;
- void setConeOuterGain(double);
+ void setConeOuterGain(double, ExceptionState&);
private:
PannerNode(BaseAudioContext&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
index 3acde7e5519..25a19fcb790 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
@@ -61,10 +61,10 @@ enum DistanceModelType {
[RaisesException=Setter] attribute double refDistance;
[RaisesException=Setter] attribute double maxDistance;
- attribute double rolloffFactor;
+ [RaisesException=Setter] attribute double rolloffFactor;
// Directional sound cone
attribute double coneInnerAngle;
attribute double coneOuterAngle;
- attribute double coneOuterGain;
+ [RaisesException=Setter] attribute double coneOuterGain;
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
index d6da662107b..7d6bce137ea 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -51,6 +51,8 @@ ScriptProcessorHandler::ScriptProcessorHandler(
unsigned number_of_output_channels)
: AudioHandler(kNodeTypeScriptProcessor, node, sample_rate),
double_buffer_index_(0),
+ input_buffers_(new HeapVector<Member<AudioBuffer>>()),
+ output_buffers_(new HeapVector<Member<AudioBuffer>>()),
buffer_size_(buffer_size),
buffer_read_write_index_(0),
number_of_input_channels_(number_of_input_channels),
@@ -115,8 +117,8 @@ void ScriptProcessorHandler::Initialize() {
sample_rate)
: nullptr;
- input_buffers_.push_back(input_buffer);
- output_buffers_.push_back(output_buffer);
+ input_buffers_->push_back(input_buffer);
+ output_buffers_->push_back(output_buffer);
}
AudioHandler::Initialize();
@@ -139,14 +141,14 @@ void ScriptProcessorHandler::Process(size_t frames_to_process) {
// sides.
unsigned double_buffer_index = this->DoubleBufferIndex();
bool is_double_buffer_index_good =
- double_buffer_index < 2 && double_buffer_index < input_buffers_.size() &&
- double_buffer_index < output_buffers_.size();
+ double_buffer_index < 2 && double_buffer_index < input_buffers_->size() &&
+ double_buffer_index < output_buffers_->size();
DCHECK(is_double_buffer_index_good);
if (!is_double_buffer_index_good)
return;
- AudioBuffer* input_buffer = input_buffers_[double_buffer_index].Get();
- AudioBuffer* output_buffer = output_buffers_[double_buffer_index].Get();
+ AudioBuffer* input_buffer = input_buffers_->at(double_buffer_index).Get();
+ AudioBuffer* output_buffer = output_buffers_->at(double_buffer_index).Get();
// Check the consistency of input and output buffers.
unsigned number_of_input_channels = internal_input_bus_->NumberOfChannels();
@@ -260,8 +262,8 @@ void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) {
if (double_buffer_index > 1)
return;
- AudioBuffer* input_buffer = input_buffers_[double_buffer_index].Get();
- AudioBuffer* output_buffer = output_buffers_[double_buffer_index].Get();
+ AudioBuffer* input_buffer = input_buffers_->at(double_buffer_index).Get();
+ AudioBuffer* output_buffer = output_buffers_->at(double_buffer_index).Get();
DCHECK(output_buffer);
if (!output_buffer)
return;
@@ -298,8 +300,8 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext(
return;
}
- AudioBuffer* input_buffer = input_buffers_[double_buffer_index].Get();
- AudioBuffer* output_buffer = output_buffers_[double_buffer_index].Get();
+ AudioBuffer* input_buffer = input_buffers_->at(double_buffer_index).Get();
+ AudioBuffer* output_buffer = output_buffers_->at(double_buffer_index).Get();
DCHECK(output_buffer);
if (!output_buffer) {
waitable_event->Signal();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
index fa04c857c96..9e658ef1453 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/platform/audio/audio_bus.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -91,8 +92,8 @@ class ScriptProcessorHandler final : public AudioHandler {
// These Persistent don't make reference cycles including the owner
// ScriptProcessorNode.
- PersistentHeapVector<Member<AudioBuffer>> input_buffers_;
- PersistentHeapVector<Member<AudioBuffer>> output_buffers_;
+ CrossThreadPersistent<HeapVector<Member<AudioBuffer>>> input_buffers_;
+ CrossThreadPersistent<HeapVector<Member<AudioBuffer>>> output_buffers_;
size_t buffer_size_;
unsigned buffer_read_write_index_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
index 4a086fd0545..010730403a6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
@@ -18,14 +18,14 @@ TEST(ScriptProcessorNodeTest, BufferLifetime) {
context->createScriptProcessor(ASSERT_NO_EXCEPTION);
ScriptProcessorHandler& handler =
static_cast<ScriptProcessorHandler&>(node->Handler());
- EXPECT_EQ(2u, handler.input_buffers_.size());
- EXPECT_EQ(2u, handler.output_buffers_.size());
+ EXPECT_EQ(2u, handler.input_buffers_->size());
+ EXPECT_EQ(2u, handler.output_buffers_->size());
BaseAudioContext::GraphAutoLocker locker(context);
handler.Dispose();
// Buffers should live after dispose() because an audio thread is using
// them.
- EXPECT_EQ(2u, handler.input_buffers_.size());
- EXPECT_EQ(2u, handler.output_buffers_.size());
+ EXPECT_EQ(2u, handler.input_buffers_->size());
+ EXPECT_EQ(2u, handler.output_buffers_->size());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
index d67ac4e3af8..c1a4560c2f8 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
@@ -72,7 +72,7 @@ const FunctionNameList& WhitelistedFunctions() {
({
// SQLite functions used to help implement some operations
// ALTER TABLE helpers
- "sqlite_rename_table", "sqlite_rename_trigger",
+ "sqlite_rename_column", "sqlite_rename_table", "sqlite_rename_test",
// GLOB helpers
"glob",
// SQLite core functions
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
index f92d64c6f79..5c936399e32 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc
@@ -51,7 +51,7 @@ DatabaseClient* DatabaseClient::FromPage(Page* page) {
}
DatabaseClient* DatabaseClient::From(ExecutionContext* context) {
- return DatabaseClient::FromPage(ToDocument(context)->GetPage());
+ return DatabaseClient::FromPage(To<Document>(context)->GetPage());
}
const char DatabaseClient::kSupplementName[] = "DatabaseClient";
@@ -61,7 +61,7 @@ bool DatabaseClient::AllowDatabase(ExecutionContext* context,
const String& display_name,
unsigned estimated_size) {
DCHECK(context->IsContextThread());
- Document* document = ToDocument(context);
+ Document* document = To<Document>(context);
DCHECK(document->GetFrame());
if (document->GetFrame()->GetContentSettingsClient()) {
return document->GetFrame()->GetContentSettingsClient()->AllowDatabase(
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
index 1f0e3ed891c..1eb9b79abff 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
@@ -175,7 +175,7 @@ void DatabaseContext::StopDatabases() {
}
bool DatabaseContext::AllowDatabaseAccess() const {
- return ToDocument(GetExecutionContext())->IsActive();
+ return To<Document>(GetExecutionContext())->IsActive();
}
const SecurityOrigin* DatabaseContext::GetSecurityOrigin() const {
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
index b0e4bc74089..919a6e193d9 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
@@ -49,7 +49,7 @@ DatabaseManager& DatabaseManager::Manager() {
return *g_database_manager;
}
-DatabaseManager::DatabaseManager() = default;
+DatabaseManager::DatabaseManager() : context_map_(new ContextMap) {}
DatabaseManager::~DatabaseManager() = default;
@@ -61,7 +61,7 @@ DatabaseContext* DatabaseManager::ExistingDatabaseContextFor(
DCHECK_LE(database_context_registered_count_,
database_context_instance_count_);
#endif
- return context_map_.at(context);
+ return context_map_->at(context);
}
DatabaseContext* DatabaseManager::DatabaseContextFor(
@@ -74,7 +74,7 @@ DatabaseContext* DatabaseManager::DatabaseContextFor(
void DatabaseManager::RegisterDatabaseContext(
DatabaseContext* database_context) {
ExecutionContext* context = database_context->GetExecutionContext();
- context_map_.Set(context, database_context);
+ context_map_->Set(context, database_context);
#if DCHECK_IS_ON()
database_context_registered_count_++;
#endif
@@ -83,11 +83,11 @@ void DatabaseManager::RegisterDatabaseContext(
void DatabaseManager::UnregisterDatabaseContext(
DatabaseContext* database_context) {
ExecutionContext* context = database_context->GetExecutionContext();
- DCHECK(context_map_.at(context));
+ DCHECK(context_map_->at(context));
#if DCHECK_IS_ON()
database_context_registered_count_--;
#endif
- context_map_.erase(context);
+ context_map_->erase(context);
}
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.h
index 9c5f2390855..3b2a79080e2 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.h
@@ -28,7 +28,7 @@
#include "third_party/blink/renderer/modules/webdatabase/database_context.h"
#include "third_party/blink/renderer/modules/webdatabase/database_error.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -102,13 +102,12 @@ class DatabaseManager {
static void LogErrorMessage(ExecutionContext*, const String& message);
- // m_contextMap can have two or more entries even though we don't support
+ // context_map_ can have two or more entries even though we don't support
// Web SQL on workers because single Blink process can have multiple main
// contexts.
- typedef PersistentHeapHashMap<Member<ExecutionContext>,
- Member<DatabaseContext>>
+ typedef HeapHashMap<Member<ExecutionContext>, Member<DatabaseContext>>
ContextMap;
- ContextMap context_map_;
+ Persistent<ContextMap> context_map_;
#if DCHECK_IS_ON()
int database_context_registered_count_ = 0;
int database_context_instance_count_ = 0;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
index ae8cb7d3adb..554d5418f73 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc
@@ -60,7 +60,7 @@ void DatabaseThread::Start() {
if (thread_)
return;
thread_ = WebThreadSupportingGC::Create(
- WebThreadCreationParams(WebThreadType::kDatabaseThread));
+ ThreadCreationParams(WebThreadType::kDatabaseThread));
thread_->PostTask(FROM_HERE,
CrossThreadBind(&DatabaseThread::SetupDatabaseThread,
WrapCrossThreadPersistent(this)));
@@ -86,7 +86,7 @@ void DatabaseThread::Terminate() {
WrapCrossThreadPersistent(this)));
}
sync.Wait();
- // The WebThread destructor blocks until all the tasks of the database
+ // The Thread destructor blocks until all the tasks of the database
// thread are processed. However, it shouldn't block at all because
// the database thread has already finished processing the cleanup task.
thread_.reset();
@@ -171,7 +171,7 @@ void DatabaseThread::ScheduleTask(std::unique_ptr<DatabaseTask> task) {
DCHECK(!termination_requested_);
}
#endif
- // WebThread takes ownership of the task.
+ // Thread takes ownership of the task.
thread_->PostTask(FROM_HERE,
CrossThreadBind(&DatabaseTask::Run, std::move(task)));
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
index b632e5f8a91..a6d1208c289 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
@@ -46,7 +46,6 @@
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -215,8 +214,7 @@ void DatabaseTracker::ForEachOpenDatabaseInPage(Page* page,
for (auto& name_database_set : *origin_map.value) {
for (Database* database : *name_database_set.value) {
ExecutionContext* context = database->GetExecutionContext();
- DCHECK(context->IsDocument());
- if (ToDocument(context)->GetFrame()->GetPage() == page)
+ if (To<Document>(context)->GetPage() == page)
callback.Run(database);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.h
index 9470898324a..36ed498a1ef 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.h
@@ -35,7 +35,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webdatabase/database_error.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
index dfb205b6933..35e5be3d4f7 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h
@@ -34,6 +34,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -55,7 +56,7 @@ class SQLTransactionCoordinator
private:
typedef Deque<CrossThreadPersistent<SQLTransactionBackend>> TransactionsQueue;
struct CoordinationInfo {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
TransactionsQueue pending_transactions;
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h
index b66442eeaec..06e25731bab 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h
@@ -35,7 +35,7 @@
namespace blink {
class SQLValue {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
enum Type { kNullValue, kNumberValue, kStringValue };
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h
index 7ea6e18b515..16717405c82 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h
@@ -29,7 +29,7 @@
#include "base/macros.h"
#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
index 987281c913b..ed1d1ab3cea 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
@@ -62,9 +62,10 @@ int SQLiteFileSystem::OpenDatabase(const String& filename, sqlite3** database) {
<< "InitializeSQLite() must be called before " << __func__;
#endif // DCHECK_IS_ON()
- return sqlite3_open_v2(filename.Utf8().data(), database,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
- "chromium_vfs");
+ return sqlite3_open_v2(
+ filename.Utf8().data(), database,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE,
+ "chromium_vfs");
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
index b8b35ff312c..db785e23255 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -27,6 +27,8 @@ blink_modules_sources("webgl") {
"ext_texture_filter_anisotropic.cc",
"ext_texture_filter_anisotropic.h",
"gl_string_query.h",
+ "khr_parallel_shader_compile.cc",
+ "khr_parallel_shader_compile.h",
"oes_element_index_uint.cc",
"oes_element_index_uint.h",
"oes_standard_derivatives.cc",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/OWNERS b/chromium/third_party/blink/renderer/modules/webgl/OWNERS
index 7429f36593d..5eeccc4842c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/webgl/OWNERS
@@ -1,4 +1,5 @@
bajones@chromium.org
+kainino@chromium.org
kbr@chromium.org
zmo@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc
new file mode 100644
index 00000000000..649ee4bee7f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
+
+#include "gpu/command_buffer/client/gles2_interface.h"
+
+namespace blink {
+
+KHRParallelShaderCompile::KHRParallelShaderCompile(
+ WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_KHR_parallel_shader_compile");
+ // Use 2 background threads per WebGL context by default.
+ context->ContextGL()->MaxShaderCompilerThreadsKHR(2);
+}
+
+WebGLExtensionName KHRParallelShaderCompile::GetName() const {
+ return kKHRParallelShaderCompileName;
+}
+
+KHRParallelShaderCompile* KHRParallelShaderCompile::Create(
+ WebGLRenderingContextBase* context) {
+ return new KHRParallelShaderCompile(context);
+}
+
+void KHRParallelShaderCompile::maxShaderCompilerThreadsKHR(GLuint count) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ // For WebGL contexts, we don't want applications to be able to spin up huge
+ // numbers of shader compliation threads. Enforce a maximum of 2 here.
+ scoped.Context()->ContextGL()->MaxShaderCompilerThreadsKHR(
+ std::min(2u, count));
+}
+
+bool KHRParallelShaderCompile::Supported(WebGLRenderingContextBase* context) {
+ return context->ExtensionsUtil()->SupportsExtension(
+ "GL_KHR_parallel_shader_compile");
+}
+
+const char* KHRParallelShaderCompile::ExtensionName() {
+ return "KHR_parallel_shader_compile";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h
new file mode 100644
index 00000000000..e777123fa9c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_KHR_PARALLEL_SHADER_COMPILE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_KHR_PARALLEL_SHADER_COMPILE_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class KHRParallelShaderCompile final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static KHRParallelShaderCompile* Create(WebGLRenderingContextBase*);
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ WebGLExtensionName GetName() const override;
+
+ void maxShaderCompilerThreadsKHR(GLuint count);
+
+ private:
+ explicit KHRParallelShaderCompile(WebGLRenderingContextBase*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_KHR_PARALLEL_SHADER_COMPILE_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl
new file mode 100644
index 00000000000..a8512340d50
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface KHRParallelShaderCompile {
+ const GLenum MAX_SHADER_COMPILER_THREADS_KHR = 0x91B0;
+ const GLenum COMPLETION_STATUS_KHR = 0x91B1;
+
+ void maxShaderCompilerThreadsKHR(GLuint count);
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
index 53d9de343c9..4e7e0c12447 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
+#include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -55,6 +57,30 @@ void WebGL2ComputeRenderingContextBase::memoryBarrierByRegion(
ContextGL()->MemoryBarrierByRegion(barriers);
}
+ScriptValue WebGL2ComputeRenderingContextBase::getParameter(
+ ScriptState* script_state,
+ GLenum pname) {
+ if (isContextLost())
+ return ScriptValue::CreateNull(script_state);
+ switch (pname) {
+ case GL_SHADING_LANGUAGE_VERSION: {
+ return WebGLAny(
+ script_state,
+ "WebGL GLSL ES 3.10 (" +
+ String(ContextGL()->GetString(GL_SHADING_LANGUAGE_VERSION)) +
+ ")");
+ }
+ case GL_VERSION: {
+ return WebGLAny(script_state,
+ "WebGL 2.0 Compute (" +
+ String(ContextGL()->GetString(GL_VERSION)) + ")");
+ }
+
+ default:
+ return WebGL2RenderingContextBase::getParameter(script_state, pname);
+ }
+}
+
void WebGL2ComputeRenderingContextBase::Trace(blink::Visitor* visitor) {
WebGL2RenderingContextBase::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
index 3339f9cb79b..39fe21eb8e8 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h
@@ -35,6 +35,7 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase {
/* WebGLRenderingContextBase overrides */
void InitializeNewContext() override;
+ ScriptValue getParameter(ScriptState*, GLenum pname) override;
void Trace(blink::Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
index c0c85e3fb14..5c3ae9ea8ae 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h"
#include "third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h"
#include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h"
+#include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
#include "third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h"
#include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h"
#include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h"
@@ -122,6 +123,8 @@ void WebGL2RenderingContext::RegisterContextExtensions() {
ext_disjoint_timer_query_web_gl2_);
RegisterExtension<EXTTextureFilterAnisotropic>(
ext_texture_filter_anisotropic_);
+ RegisterExtension<KHRParallelShaderCompile>(khr_parallel_shader_compile_,
+ kDraftExtension);
RegisterExtension<OESTextureFloatLinear>(oes_texture_float_linear_);
RegisterExtension<WebGLCompressedTextureASTC>(webgl_compressed_texture_astc_);
RegisterExtension<WebGLCompressedTextureETC>(webgl_compressed_texture_etc_);
@@ -141,6 +144,7 @@ void WebGL2RenderingContext::Trace(blink::Visitor* visitor) {
visitor->Trace(ext_color_buffer_float_);
visitor->Trace(ext_disjoint_timer_query_web_gl2_);
visitor->Trace(ext_texture_filter_anisotropic_);
+ visitor->Trace(khr_parallel_shader_compile_);
visitor->Trace(oes_texture_float_linear_);
visitor->Trace(webgl_compressed_texture_astc_);
visitor->Trace(webgl_compressed_texture_etc_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
index 1db2acea31e..4b6f24ea49a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
@@ -18,6 +18,7 @@ class OESTextureFloatLinear;
class WebGLDebugRendererInfo;
class WebGLLoseContext;
class WebGLMultiview;
+class KHRParallelShaderCompile;
class WebGL2RenderingContext : public WebGL2RenderingContextBase {
DEFINE_WRAPPERTYPEINFO();
@@ -60,6 +61,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
Member<EXTColorBufferFloat> ext_color_buffer_float_;
Member<EXTDisjointTimerQueryWebGL2> ext_disjoint_timer_query_web_gl2_;
Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
+ Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
Member<OESTextureFloatLinear> oes_texture_float_linear_;
Member<WebGLCompressedTextureASTC> webgl_compressed_texture_astc_;
Member<WebGLCompressedTextureETC> webgl_compressed_texture_etc_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
index 3846b2a179d..26b4610c87c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
@@ -22,6 +22,7 @@ WebGLContextAttributes ToWebGLContextAttributes(
attrs.fail_if_major_performance_caveat);
result.setCompatibleXRDevice(
static_cast<XRDevice*>(attrs.compatible_xr_device.Get()));
+ result.setLowLatency(attrs.low_latency);
return result;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
index 38ca0f6b6a0..39092f2acab 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
@@ -35,4 +35,6 @@ dictionary WebGLContextAttributes {
boolean preserveDrawingBuffer = false;
boolean failIfMajorPerformanceCaveat = false;
[OriginTrialEnabled=WebXR] XRDevice compatibleXRDevice = null;
+ // TODO(crbug.com/788439): remove OriginTrialEnabled.
+ [OriginTrialEnabled=LowLatencyCanvas] boolean lowLatency = false;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
index f3e544031f2..786b9e1230b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
@@ -18,6 +18,7 @@ enum WebGLExtensionName {
kEXTFragDepthName,
kEXTShaderTextureLODName,
kEXTsRGBName,
+ kKHRParallelShaderCompileName,
kEXTTextureFilterAnisotropicName,
kOESElementIndexUintName,
kOESStandardDerivativesName,
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
index 4c6e51707f4..dc72854384c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
@@ -74,6 +74,14 @@ bool WebGLProgram::LinkStatus(WebGLRenderingContextBase* context) {
return link_status_;
}
+bool WebGLProgram::CompletionStatus(WebGLRenderingContextBase* context) {
+ GLint completed = 0;
+ gpu::gles2::GLES2Interface* gl = context->ContextGL();
+ gl->GetProgramiv(object_, GL_COMPLETION_STATUS_KHR, &completed);
+
+ return completed;
+}
+
void WebGLProgram::IncreaseLinkCount() {
++link_count_;
info_valid_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
index 40f0042022e..d70c358163b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
@@ -43,6 +43,8 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject {
bool LinkStatus(WebGLRenderingContextBase*);
+ bool CompletionStatus(WebGLRenderingContextBase*);
+
unsigned LinkCount() const { return link_count_; }
// This is to be called everytime after the program is successfully linked.
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
index c5d482bba1d..059b718a360 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h"
#include "third_party/blink/renderer/modules/webgl/ext_srgb.h"
#include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h"
+#include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
#include "third_party/blink/renderer/modules/webgl/oes_element_index_uint.h"
#include "third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h"
#include "third_party/blink/renderer/modules/webgl/oes_texture_float.h"
@@ -158,6 +159,8 @@ void WebGLRenderingContext::RegisterContextExtensions() {
RegisterExtension<EXTTextureFilterAnisotropic>(
ext_texture_filter_anisotropic_, kApprovedExtension, kBothPrefixes);
RegisterExtension<EXTsRGB>(exts_rgb_);
+ RegisterExtension<KHRParallelShaderCompile>(khr_parallel_shader_compile_,
+ kDraftExtension);
RegisterExtension<OESElementIndexUint>(oes_element_index_uint_);
RegisterExtension<OESStandardDerivatives>(oes_standard_derivatives_);
RegisterExtension<OESTextureFloat>(oes_texture_float_);
@@ -194,6 +197,7 @@ void WebGLRenderingContext::Trace(blink::Visitor* visitor) {
visitor->Trace(ext_shader_texture_lod_);
visitor->Trace(ext_texture_filter_anisotropic_);
visitor->Trace(exts_rgb_);
+ visitor->Trace(khr_parallel_shader_compile_);
visitor->Trace(oes_element_index_uint_);
visitor->Trace(oes_standard_derivatives_);
visitor->Trace(oes_texture_float_);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
index 5d13ec8aed7..46b21b8d8af 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
@@ -40,6 +40,7 @@ class EXTFragDepth;
class EXTShaderTextureLOD;
class EXTsRGB;
class EXTTextureFilterAnisotropic;
+class KHRParallelShaderCompile;
class OESElementIndexUint;
class OESStandardDerivatives;
class OESTextureFloat;
@@ -98,6 +99,7 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase {
Member<EXTShaderTextureLOD> ext_shader_texture_lod_;
Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
Member<EXTsRGB> exts_rgb_;
+ Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
Member<OESElementIndexUint> oes_element_index_uint_;
Member<OESStandardDerivatives> oes_standard_derivatives_;
Member<OESTextureFloat> oes_texture_float_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 051cb2897f0..2d312c67b97 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -1119,7 +1119,7 @@ void WebGLRenderingContextBase::InitializeNewContext() {
// into account here?
marked_canvas_dirty_ = false;
- animation_frame_in_progress_ = false;
+ must_paint_to_canvas_ = false;
active_texture_unit_ = 0;
pack_alignment_ = 4;
unpack_alignment_ = 4;
@@ -1348,6 +1348,11 @@ void WebGLRenderingContextBase::MarkContextChanged(
return;
}
+ // Regardless of whether dirty propagations are optimized away, the back
+ // buffer is now out of sync with respect to the canvas's internal backing
+ // store -- which is only used for certain purposes, like printing.
+ must_paint_to_canvas_ = true;
+
if (!GetDrawingBuffer()->MarkContentsChanged() && marked_canvas_dirty_) {
return;
}
@@ -1361,10 +1366,8 @@ void WebGLRenderingContextBase::MarkContextChanged(
if (!canvas())
return;
- marked_canvas_dirty_ = true;
-
- if (!animation_frame_in_progress_) {
- animation_frame_in_progress_ = true;
+ if (!marked_canvas_dirty_) {
+ marked_canvas_dirty_ = true;
LayoutBox* layout_box = canvas()->GetLayoutBox();
if (layout_box && layout_box->HasAcceleratedCompositing()) {
layout_box->ContentChanged(change_type);
@@ -1397,7 +1400,7 @@ void WebGLRenderingContextBase::PushFrame() {
}
void WebGLRenderingContextBase::FinalizeFrame() {
- animation_frame_in_progress_ = false;
+ marked_canvas_dirty_ = false;
}
void WebGLRenderingContextBase::OnErrorMessage(const char* message,
@@ -1545,10 +1548,10 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas(
return false;
bool must_clear_now = ClearIfComposited() != kSkipped;
- if (!marked_canvas_dirty_ && !must_clear_now)
+ if (!must_paint_to_canvas_ && !must_clear_now)
return false;
- marked_canvas_dirty_ = false;
+ must_paint_to_canvas_ = false;
if (Host()->ResourceProvider() &&
Host()->ResourceProvider()->Size() != GetDrawingBuffer()->Size()) {
@@ -1602,8 +1605,9 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
// CopyToPlatformTexture is done correctly. See crbug.com/794706.
gl->Flush();
+ bool flip_y = is_origin_top_left_ && !canvas()->LowLatencyEnabled();
return drawing_buffer_->CopyToPlatformTexture(
- gl, GL_TEXTURE_2D, texture_id, true, is_origin_top_left_,
+ gl, GL_TEXTURE_2D, texture_id, true, flip_y,
IntPoint(0, 0), IntRect(IntPoint(0, 0), drawing_buffer_->Size()),
source_buffer);
}
@@ -1614,8 +1618,10 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration);
if (!image)
return false;
+ cc::PaintFlags paint_flags;
+ paint_flags.setBlendMode(SkBlendMode::kSrc);
resource_provider->Canvas()->drawImage(image->PaintImageForCurrentFrame(), 0,
- 0, nullptr);
+ 0, &paint_flags);
return true;
}
@@ -3342,6 +3348,13 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state,
SynthesizeGLError(GL_INVALID_ENUM, "getParameter",
"invalid parameter name, WEBGL_multiview not enabled");
return ScriptValue::CreateNull(script_state);
+ case GL_MAX_SHADER_COMPILER_THREADS_KHR:
+ if (ExtensionEnabled(kKHRParallelShaderCompileName))
+ return GetUnsignedIntParameter(script_state, pname);
+ SynthesizeGLError(
+ GL_INVALID_ENUM, "getParameter",
+ "invalid parameter name, KHR_parallel_shader_compile not enabled");
+ return ScriptValue::CreateNull(script_state);
default:
if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) &&
pname >= GL_DRAW_BUFFER0_EXT &&
@@ -3375,6 +3388,14 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter(
return WebGLAny(script_state, static_cast<bool>(value));
case GL_LINK_STATUS:
return WebGLAny(script_state, program->LinkStatus(this));
+ case GL_COMPLETION_STATUS_KHR:
+ if (!ExtensionEnabled(kKHRParallelShaderCompileName)) {
+ SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state);
+ }
+
+ return WebGLAny(script_state, program->CompletionStatus(this));
case GL_ACTIVE_UNIFORM_BLOCKS:
case GL_TRANSFORM_FEEDBACK_VARYINGS:
if (!IsWebGL2OrHigher()) {
@@ -3468,6 +3489,14 @@ ScriptValue WebGLRenderingContextBase::getShaderParameter(
case GL_COMPILE_STATUS:
ContextGL()->GetShaderiv(ObjectOrZero(shader), pname, &value);
return WebGLAny(script_state, static_cast<bool>(value));
+ case GL_COMPLETION_STATUS_KHR:
+ if (!ExtensionEnabled(kKHRParallelShaderCompileName)) {
+ SynthesizeGLError(GL_INVALID_ENUM, "getShaderParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state);
+ }
+ ContextGL()->GetShaderiv(ObjectOrZero(shader), pname, &value);
+ return WebGLAny(script_state, static_cast<bool>(value));
case GL_SHADER_TYPE:
ContextGL()->GetShaderiv(ObjectOrZero(shader), pname, &value);
return WebGLAny(script_state, static_cast<unsigned>(value));
@@ -5175,7 +5204,7 @@ void WebGLRenderingContextBase::TexImageViaGPU(
IntPoint(xoffset, yoffset), source_sub_rectangle);
} else {
WebGLRenderingContextBase* gl = source_canvas_webgl_context;
- if (gl->is_origin_top_left_)
+ if (gl->is_origin_top_left_ && !canvas()->LowLatencyEnabled())
flip_y = !flip_y;
ScopedTexture2DRestorer restorer(gl);
if (!gl->GetDrawingBuffer()->CopyToPlatformTexture(
@@ -5409,6 +5438,9 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
yoffset, zoffset))
return;
+ GLint adjusted_internalformat =
+ ConvertTexInternalFormat(internalformat, type);
+
// For WebGL last-uploaded-frame-metadata API. https://crbug.com/639174
WebMediaPlayer::VideoFrameUploadMetadata frame_metadata = {};
int already_uploaded_id = -1;
@@ -5447,8 +5479,8 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
// SW path.
if (video->CopyVideoTextureToPlatformTexture(
- ContextGL(), target, texture->Object(), internalformat, format,
- type, level, unpack_premultiply_alpha_, unpack_flip_y_,
+ ContextGL(), target, texture->Object(), adjusted_internalformat,
+ format, type, level, unpack_premultiply_alpha_, unpack_flip_y_,
already_uploaded_id, frame_metadata_ptr)) {
texture->UpdateLastUploadedFrame(frame_metadata);
return;
@@ -5458,8 +5490,8 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
// (e.g. video camera frames): upload them to the GPU, do a GPU decode, and
// then copy into the target texture.
if (video->CopyVideoYUVDataToPlatformTexture(
- ContextGL(), target, texture->Object(), internalformat, format,
- type, level, unpack_premultiply_alpha_, unpack_flip_y_,
+ ContextGL(), target, texture->Object(), adjusted_internalformat,
+ format, type, level, unpack_premultiply_alpha_, unpack_flip_y_,
already_uploaded_id, frame_metadata_ptr)) {
texture->UpdateLastUploadedFrame(frame_metadata);
return;
@@ -5474,8 +5506,8 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
if (video->TexImageImpl(
static_cast<WebMediaPlayer::TexImageFunctionID>(function_id),
target, ContextGL(), texture->Object(), level,
- ConvertTexInternalFormat(internalformat, type), format, type,
- xoffset, yoffset, zoffset, unpack_flip_y_,
+ adjusted_internalformat, format, type, xoffset, yoffset, zoffset,
+ unpack_flip_y_,
unpack_premultiply_alpha_ &&
unpack_colorspace_conversion_ == GL_NONE)) {
texture->ClearLastUploadedFrame();
@@ -5487,8 +5519,8 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
VideoFrameToImage(video, already_uploaded_id, frame_metadata_ptr);
if (!image)
return;
- TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
- zoffset, format, type, image.get(),
+ TexImageImpl(function_id, target, level, adjusted_internalformat, xoffset,
+ yoffset, zoffset, format, type, image.get(),
WebGLImageConversion::kHtmlDomVideo, unpack_flip_y_,
unpack_premultiply_alpha_, source_image_rect, depth,
unpack_image_height);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 424f8bcf4f6..96c15706bcf 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -580,7 +580,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
DrawingBuffer* GetDrawingBuffer() const;
class TextureUnitState {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
public:
TraceWrapperMember<WebGLTexture> texture2d_binding_;
@@ -730,7 +730,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool destruction_in_progress_ = false;
bool marked_canvas_dirty_;
- bool animation_frame_in_progress_;
+ // For performance reasons we must separately track whether we've
+ // copied WebGL's drawing buffer to the canvas's backing store, for
+ // example for printing.
+ bool must_paint_to_canvas_;
// List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and
// stored values for ELEMENT_ARRAY_BUFFER
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
index 884e88aa912..1d64eac6069 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
@@ -69,8 +69,7 @@ MIDIAccess::MIDIAccess(
sysex_enabled_(sysex_enabled),
has_pending_activity_(false) {
accessor_->SetClient(this);
- for (size_t i = 0; i < ports.size(); ++i) {
- const MIDIAccessInitializer::PortDescriptor& port = ports[i];
+ for (const auto& port : ports) {
if (port.type == MIDIPort::kTypeInput) {
inputs_.push_back(MIDIInput::Create(this, port.id, port.manufacturer,
port.name, port.version,
@@ -106,8 +105,7 @@ bool MIDIAccess::HasPendingActivity() const {
MIDIInputMap* MIDIAccess::inputs() const {
HeapVector<Member<MIDIInput>> inputs;
HashSet<String> ids;
- for (size_t i = 0; i < inputs_.size(); ++i) {
- MIDIInput* input = inputs_[i];
+ for (MIDIInput* input : inputs_) {
if (input->GetState() != PortState::DISCONNECTED) {
inputs.push_back(input);
ids.insert(input->id());
@@ -123,8 +121,7 @@ MIDIInputMap* MIDIAccess::inputs() const {
MIDIOutputMap* MIDIAccess::outputs() const {
HeapVector<Member<MIDIOutput>> outputs;
HashSet<String> ids;
- for (size_t i = 0; i < outputs_.size(); ++i) {
- MIDIOutput* output = outputs_[i];
+ for (MIDIOutput* output : outputs_) {
if (output->GetState() != PortState::DISCONNECTED) {
outputs.push_back(output);
ids.insert(output->id());
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
index 33a8b5b3175..5db5ab3f029 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc
@@ -43,10 +43,10 @@ ScriptPromise MIDIAccessInitializer::Start() {
ConnectToPermissionService(GetExecutionContext(),
mojo::MakeRequest(&permission_service_));
- Document* doc = ToDocumentOrNull(GetExecutionContext());
+ Document& doc = To<Document>(*GetExecutionContext());
permission_service_->RequestPermission(
CreateMidiPermissionDescriptor(options_.hasSysex() && options_.sysex()),
- Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
+ LocalFrame::HasTransientUserActivation(doc.GetFrame()),
WTF::Bind(&MIDIAccessInitializer::OnPermissionsUpdated,
WrapPersistent(this)));
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
index 2a2da55db34..ef1e7d4d84b 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h
@@ -26,7 +26,7 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
public MIDIAccessorClient {
public:
struct PortDescriptor {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ DISALLOW_NEW();
String id;
String manufacturer;
String name;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
index 0992d957d1d..65395387832 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
@@ -101,7 +101,7 @@ void MIDIInput::DidReceiveMIDIData(unsigned port_index,
DOMUint8Array* array = DOMUint8Array::Create(data, length);
DispatchEvent(*MIDIMessageEvent::Create(time_stamp, array));
- UseCounter::Count(*ToDocument(GetExecutionContext()),
+ UseCounter::Count(*To<Document>(GetExecutionContext()),
WebFeature::kMIDIMessageEvent);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
index 2c712d16ac9..9c087cbbad3 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
@@ -53,7 +53,7 @@ DOMUint8Array* ConvertUnsignedDataToUint8Array(
ExceptionState& exception_state) {
DOMUint8Array* array = DOMUint8Array::Create(unsigned_data.size());
DOMUint8Array::ValueType* array_data = array->Data();
- for (size_t i = 0; i < unsigned_data.size(); ++i) {
+ for (wtf_size_t i = 0; i < unsigned_data.size(); ++i) {
if (unsigned_data[i] > 0xff) {
exception_state.ThrowTypeError("The value at index " + String::Number(i) +
" (" + String::Number(unsigned_data[i]) +
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
index da3e04f5abc..776eaa6d9fe 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -198,7 +198,7 @@ void MIDIPort::OpenAsynchronously(ScriptPromiseResolver* resolver) {
if (!GetExecutionContext())
return;
- UseCounter::Count(*ToDocument(GetExecutionContext()),
+ UseCounter::Count(*To<Document>(GetExecutionContext()),
WebFeature::kMIDIPortOpen);
DCHECK_NE(0u, running_open_count_);
running_open_count_--;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
index 5961c6b1f8a..51db70ef437 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h
@@ -21,7 +21,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> {
: entries_(entries) {}
// IDL attributes / methods
- size_t size() const { return entries_.size(); }
+ uint32_t size() const { return entries_.size(); }
void Trace(blink::Visitor* visitor) override {
visitor->Trace(entries_);
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
index 4d08522cff1..aa7c5fbf746 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc
@@ -89,7 +89,7 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
"The frame is not working."));
}
- Document& document = *ToDocument(ExecutionContext::From(script_state));
+ Document& document = *To<Document>(ExecutionContext::From(script_state));
if (options.hasSysex() && options.sysex()) {
UseCounter::Count(
document,
@@ -102,9 +102,8 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
UseCounter::CountCrossOriginIframe(
document, WebFeature::kRequestMIDIAccessIframe_ObscuredByFootprinting);
- if (!document.GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kMidiFeature,
- ReportOptions::kReportOnFailure)) {
+ if (!document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kMidiFeature,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document, WebFeature::kMidiDisabledByFeaturePolicy);
document.AddConsoleMessage(ConsoleMessage::Create(
kJSMessageSource, kWarningMessageLevel, kFeaturePolicyConsoleWarning));
diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
index dca964a2ab1..a1495b090ca 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
@@ -102,8 +102,7 @@ const char NavigatorShare::kSupplementName[] = "NavigatorShare";
ScriptPromise NavigatorShare::share(ScriptState* script_state,
const ShareData& share_data) {
- Document* doc = ToDocument(ExecutionContext::From(script_state));
- DCHECK(doc);
+ Document* doc = To<Document>(ExecutionContext::From(script_state));
if (!share_data.hasTitle() && !share_data.hasText() && !share_data.hasURL()) {
v8::Local<v8::Value> error = V8ThrowException::CreateTypeError(
@@ -120,7 +119,7 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
return ScriptPromise::Reject(script_state, error);
}
- if (!Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ if (!LocalFrame::HasTransientUserActivation(doc->GetFrame())) {
DOMException* error = DOMException::Create(
DOMExceptionCode::kNotAllowedError,
"Must be handling a user gesture to perform a share request.");
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index 5e643649ae6..8d10617e9f6 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -30,7 +30,9 @@
#include "third_party/blink/renderer/modules/websockets/dom_websocket.h"
+#include "base/feature_list.h"
#include "base/location.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h"
@@ -47,6 +49,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/modules/websockets/close_event.h"
@@ -54,6 +57,7 @@
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/loader/mixed_content_autoupgrade_status.h"
#include "third_party/blink/renderer/platform/network/network_log.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -63,11 +67,20 @@
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
static const size_t kMaxByteSizeForHistogram = 100 * 1000 * 1000;
static const int32_t kBucketCountForMessageSizeHistogram = 50;
static const char kWebSocketSubprotocolSeparator[] = ", ";
+namespace {
+void LogMixedAutoupgradeStatus(blink::MixedContentAutoupgradeStatus status) {
+ // For websockets we use the response received element to log successful
+ // connections.
+ UMA_HISTOGRAM_ENUMERATION("MixedAutoupgrade.Websocket.Status", status);
+}
+} // namespace
+
namespace blink {
DOMWebSocket::EventQueue::EventQueue(EventTarget* target)
@@ -185,7 +198,7 @@ static inline bool IsValidSubprotocolCharacter(UChar character) {
bool DOMWebSocket::IsValidSubprotocolString(const String& protocol) {
if (protocol.IsEmpty())
return false;
- for (size_t i = 0; i < protocol.length(); ++i) {
+ for (wtf_size_t i = 0; i < protocol.length(); ++i) {
if (!IsValidSubprotocolCharacter(protocol[i]))
return false;
}
@@ -194,7 +207,7 @@ bool DOMWebSocket::IsValidSubprotocolString(const String& protocol) {
static String EncodeSubprotocolString(const String& protocol) {
StringBuilder builder;
- for (size_t i = 0; i < protocol.length(); i++) {
+ for (wtf_size_t i = 0; i < protocol.length(); i++) {
if (protocol[i] < 0x20 || protocol[i] > 0x7E)
builder.Append(String::Format("\\u%04X", protocol[i]));
else if (protocol[i] == 0x5c)
@@ -208,7 +221,7 @@ static String EncodeSubprotocolString(const String& protocol) {
static String JoinStrings(const Vector<String>& strings,
const char* separator) {
StringBuilder builder;
- for (size_t i = 0; i < strings.size(); ++i) {
+ for (wtf_size_t i = 0; i < strings.size(); ++i) {
if (i)
builder.Append(separator);
builder.Append(strings[i]);
@@ -231,7 +244,8 @@ DOMWebSocket::DOMWebSocket(ExecutionContext* context)
subprotocol_(""),
extensions_(""),
event_queue_(EventQueue::Create(this)),
- buffered_amount_update_task_pending_(false) {}
+ buffered_amount_update_task_pending_(false),
+ was_autoupgraded_to_wss_(false) {}
DOMWebSocket::~DOMWebSocket() {
DCHECK(!channel_);
@@ -291,10 +305,20 @@ void DOMWebSocket::Connect(const String& url,
NETWORK_DVLOG(1) << "WebSocket " << this << " connect() url=" << url;
url_ = KURL(NullURL(), url);
- if (GetExecutionContext()->GetSecurityContext().GetInsecureRequestPolicy() &
- kUpgradeInsecureRequests &&
+ bool upgrade_insecure_requests_set =
+ GetExecutionContext()->GetSecurityContext().GetInsecureRequestPolicy() &
+ kUpgradeInsecureRequests;
+
+ if ((upgrade_insecure_requests_set ||
+ MixedContentChecker::ShouldAutoupgrade(
+ GetExecutionContext()->Url(),
+ WebMixedContentContextType::kBlockable)) &&
url_.Protocol() == "ws" &&
!SecurityOrigin::Create(url_)->IsPotentiallyTrustworthy()) {
+ if (!upgrade_insecure_requests_set) {
+ was_autoupgraded_to_wss_ = true;
+ LogMixedAutoupgradeStatus(MixedContentAutoupgradeStatus::kStarted);
+ }
UseCounter::Count(GetExecutionContext(),
WebFeature::kUpgradeInsecureRequestsUpgradedRequest);
url_.SetProtocol("wss");
@@ -349,26 +373,26 @@ void DOMWebSocket::Connect(const String& url,
}
// Fail if not all elements in |protocols| are valid.
- for (size_t i = 0; i < protocols.size(); ++i) {
- if (!IsValidSubprotocolString(protocols[i])) {
+ for (const String& protocol : protocols) {
+ if (!IsValidSubprotocolString(protocol)) {
state_ = kClosed;
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "The subprotocol '" + EncodeSubprotocolString(protocols[i]) +
- "' is invalid.");
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "The subprotocol '" +
+ EncodeSubprotocolString(protocol) +
+ "' is invalid.");
return;
}
}
// Fail if there're duplicated elements in |protocols|.
HashSet<String> visited;
- for (size_t i = 0; i < protocols.size(); ++i) {
- if (!visited.insert(protocols[i]).is_new_entry) {
+ for (const String& protocol : protocols) {
+ if (!visited.insert(protocol).is_new_entry) {
state_ = kClosed;
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "The subprotocol '" + EncodeSubprotocolString(protocols[i]) +
- "' is duplicated.");
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "The subprotocol '" +
+ EncodeSubprotocolString(protocol) +
+ "' is duplicated.");
return;
}
}
@@ -678,6 +702,8 @@ void DOMWebSocket::Unpause() {
void DOMWebSocket::DidConnect(const String& subprotocol,
const String& extensions) {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidConnect()";
+ if (was_autoupgraded_to_wss_)
+ LogMixedAutoupgradeStatus(MixedContentAutoupgradeStatus::kResponseReceived);
if (state_ != kConnecting)
return;
state_ = kOpen;
@@ -739,6 +765,8 @@ void DOMWebSocket::DidReceiveBinaryMessage(
void DOMWebSocket::DidError() {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidError()";
+ if (state_ == kConnecting && was_autoupgraded_to_wss_)
+ LogMixedAutoupgradeStatus(MixedContentAutoupgradeStatus::kFailed);
ReflectBufferedAmountConsumption();
state_ = kClosed;
event_queue_->Dispatch(Event::Create(EventTypeNames::error));
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
index 4278acea08c..5511d12644a 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -266,6 +266,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
Member<EventQueue> event_queue_;
bool buffered_amount_update_task_pending_;
+
+ bool was_autoupgraded_to_wss_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
index f46924e609f..784928d791f 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
@@ -6,8 +6,10 @@
#include <memory>
+#include "base/test/scoped_feature_list.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_insecure_request_policy.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
@@ -267,6 +269,27 @@ TEST(DOMWebSocketTest, insecureRequestsDoNotUpgrade) {
EXPECT_EQ(KURL("ws://example.com/endpoint"), websocket_scope.Socket().url());
}
+TEST(DOMWebSocketTest, mixedContentAutoUpgrade) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(features::kMixedContentAutoupgrade);
+ V8TestingScope scope;
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
+ {
+ InSequence s;
+ EXPECT_CALL(websocket_scope.Channel(),
+ Connect(KURL("wss://example.com/endpoint"), String()))
+ .WillOnce(Return(true));
+ }
+ scope.GetDocument().SetURL(KURL("https://example.com"));
+ scope.GetDocument().SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
+ websocket_scope.Socket().Connect("ws://example.com/endpoint",
+ Vector<String>(), scope.GetExceptionState());
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ EXPECT_EQ(DOMWebSocket::kConnecting, websocket_scope.Socket().readyState());
+ EXPECT_EQ(KURL("wss://example.com/endpoint"), websocket_scope.Socket().url());
+}
+
TEST(DOMWebSocketTest, channelConnectSuccess) {
V8TestingScope scope;
DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
diff --git a/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc b/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
index ea3e2460d7d..f94cb8d91ea 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
@@ -22,11 +22,11 @@ std::unique_ptr<TracedValue> InspectorWebSocketCreateEvent::Data(
const String& protocol) {
DCHECK(execution_context->IsContextThread());
std::unique_ptr<TracedValue> value = TracedValue::Create();
- value->SetInteger("identifier", identifier);
+ value->SetInteger("identifier", static_cast<int>(identifier));
value->SetString("url", url.GetString());
- if (execution_context->IsDocument()) {
- value->SetString("frame", IdentifiersFactory::FrameId(
- ToDocument(execution_context)->GetFrame()));
+ if (auto* document = DynamicTo<Document>(execution_context)) {
+ value->SetString("frame",
+ IdentifiersFactory::FrameId(document->GetFrame()));
} else if (execution_context->IsWorkerGlobalScope()) {
value->SetString("workerId", IdentifiersFactory::IdFromToken(
ToWorkerGlobalScope(execution_context)
@@ -47,10 +47,10 @@ std::unique_ptr<TracedValue> InspectorWebSocketEvent::Data(
unsigned long identifier) {
DCHECK(execution_context->IsContextThread());
std::unique_ptr<TracedValue> value = TracedValue::Create();
- value->SetInteger("identifier", identifier);
- if (execution_context->IsDocument()) {
- value->SetString("frame", IdentifiersFactory::FrameId(
- ToDocument(execution_context)->GetFrame()));
+ value->SetInteger("identifier", static_cast<int>(identifier));
+ if (auto* document = DynamicTo<Document>(execution_context)) {
+ value->SetString("frame",
+ IdentifiersFactory::FrameId(document->GetFrame()));
} else if (execution_context->IsWorkerGlobalScope()) {
value->SetString("workerId", IdentifiersFactory::IdFromToken(
ToWorkerGlobalScope(execution_context)
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
index c7755b7977e..f08c1c4b9fe 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -62,6 +62,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
@@ -428,16 +429,16 @@ WebSocketChannelImpl::Message::Message(unsigned short code,
void WebSocketChannelImpl::SendInternal(
WebSocketHandle::MessageType message_type,
const char* data,
- size_t total_size,
+ wtf_size_t total_size,
uint64_t* consumed_buffered_amount) {
WebSocketHandle::MessageType frame_type =
sent_size_of_top_message_ ? WebSocketHandle::kMessageTypeContinuation
: message_type;
DCHECK_GE(total_size, sent_size_of_top_message_);
// The first cast is safe since the result of min() never exceeds
- // the range of size_t. The second cast is necessary to compile
+ // the range of wtf_size_t. The second cast is necessary to compile
// min() on ILP32.
- size_t size = static_cast<size_t>(
+ wtf_size_t size = static_cast<wtf_size_t>(
std::min(sending_quota_,
static_cast<uint64_t>(total_size - sent_size_of_top_message_)));
bool final = (sent_size_of_top_message_ + size == total_size);
@@ -650,7 +651,7 @@ void WebSocketChannelImpl::DidReceiveData(WebSocketHandle* handle,
break;
}
- receiving_message_data_.Append(data, size);
+ receiving_message_data_.Append(data, SafeCast<uint32_t>(size));
received_data_size_for_flow_control_ += size;
FlowControlIfNecessary();
if (!fin) {
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
index dfb664c18db..121dca5eccc 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -51,6 +51,7 @@
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace blink {
@@ -133,7 +134,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
void SendInternal(WebSocketHandle::MessageType,
const char* data,
- size_t total_size,
+ wtf_size_t total_size,
uint64_t* consumed_buffered_amount);
void ProcessSendQueue();
void FlowControlIfNecessary();
@@ -200,7 +201,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
bool receiving_message_type_is_text_;
uint64_t sending_quota_;
uint64_t received_data_size_for_flow_control_;
- size_t sent_size_of_top_message_;
+ wtf_size_t sent_size_of_top_message_;
std::unique_ptr<FrameScheduler::ActiveConnectionHandle>
connection_handle_for_scheduler_;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
index ccc4d0521a7..c13eb980d9f 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
using testing::_;
using testing::InSequence;
@@ -96,8 +97,9 @@ class MockWebSocketHandle : public WebSocketHandle {
const KURL&,
const String&,
WebSocketHandleClient*));
- MOCK_METHOD4(Send,
- void(bool, WebSocketHandle::MessageType, const char*, size_t));
+ MOCK_METHOD4(
+ Send,
+ void(bool, WebSocketHandle::MessageType, const char*, wtf_size_t));
MOCK_METHOD1(FlowControl, void(int64_t));
MOCK_METHOD2(Close, void(unsigned short, const String&));
};
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle.h
index 464adb305fa..4a7c0402c76 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle.h
@@ -36,6 +36,7 @@
#include "services/network/public/mojom/websocket.mojom-blink.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace blink {
@@ -67,7 +68,7 @@ class WebSocketHandle {
const String& user_agent_override,
WebSocketHandleClient*,
base::SingleThreadTaskRunner*) = 0;
- virtual void Send(bool fin, MessageType, const char* data, size_t) = 0;
+ virtual void Send(bool fin, MessageType, const char* data, wtf_size_t) = 0;
virtual void FlowControl(int64_t quota) = 0;
virtual void Close(unsigned short code, const String& reason) = 0;
};
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
index 079a508ddff..2d052f9b2d3 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
@@ -67,7 +67,7 @@ void WebSocketHandleImpl::Connect(network::mojom::blink::WebSocketPtr websocket,
void WebSocketHandleImpl::Send(bool fin,
WebSocketHandle::MessageType type,
const char* data,
- size_t size) {
+ wtf_size_t size) {
DCHECK(websocket_);
network::mojom::blink::WebSocketMessageType type_to_pass;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h
index 0e16a3ed8e7..9f89fd6cc5b 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h
@@ -34,6 +34,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/websocket.mojom-blink.h"
#include "third_party/blink/renderer/modules/websockets/websocket_handle.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace blink {
@@ -50,7 +51,7 @@ class WebSocketHandleImpl : public WebSocketHandle,
const String& user_agent_override,
WebSocketHandleClient*,
base::SingleThreadTaskRunner*) override;
- void Send(bool fin, MessageType, const char* data, size_t) override;
+ void Send(bool fin, MessageType, const char* data, wtf_size_t) override;
void FlowControl(int64_t quota) override;
void Close(unsigned short code, const String& reason) override;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
index 6f96c1ae804..5da4060b792 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -8,6 +8,7 @@
#include "device/usb/public/mojom/device.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -19,7 +20,6 @@
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
#include "third_party/blink/renderer/modules/webusb/usb_device_filter.h"
#include "third_party/blink/renderer/modules/webusb/usb_device_request_options.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -34,23 +34,53 @@ const char kFeaturePolicyBlocked[] =
"Access to the feature \"usb\" is disallowed by feature policy.";
const char kNoDeviceSelected[] = "No device selected.";
-UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter) {
+void RejectWithTypeError(const String& error_details,
+ ScriptPromiseResolver* resolver) {
+ ScriptState::Scope scope(resolver->GetScriptState());
+ v8::Isolate* isolate = resolver->GetScriptState()->GetIsolate();
+ resolver->Reject(V8ThrowException::CreateTypeError(isolate, error_details));
+}
+
+UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter& filter,
+ ScriptPromiseResolver* resolver) {
auto mojo_filter = device::mojom::blink::UsbDeviceFilter::New();
mojo_filter->has_vendor_id = filter.hasVendorId();
if (mojo_filter->has_vendor_id)
mojo_filter->vendor_id = filter.vendorId();
mojo_filter->has_product_id = filter.hasProductId();
- if (mojo_filter->has_product_id)
+ if (mojo_filter->has_product_id) {
+ if (!mojo_filter->has_vendor_id) {
+ RejectWithTypeError(
+ "A filter containing a productId must also contain a vendorId.",
+ resolver);
+ return nullptr;
+ }
mojo_filter->product_id = filter.productId();
+ }
mojo_filter->has_class_code = filter.hasClassCode();
if (mojo_filter->has_class_code)
mojo_filter->class_code = filter.classCode();
mojo_filter->has_subclass_code = filter.hasSubclassCode();
- if (mojo_filter->has_subclass_code)
+ if (mojo_filter->has_subclass_code) {
+ if (!mojo_filter->has_class_code) {
+ RejectWithTypeError(
+ "A filter containing a subclassCode must also contain a classCode.",
+ resolver);
+ return nullptr;
+ }
mojo_filter->subclass_code = filter.subclassCode();
+ }
mojo_filter->has_protocol_code = filter.hasProtocolCode();
- if (mojo_filter->has_protocol_code)
+ if (mojo_filter->has_protocol_code) {
+ if (!mojo_filter->has_subclass_code) {
+ RejectWithTypeError(
+ "A filter containing a protocolCode must also contain a "
+ "subclassCode.",
+ resolver);
+ return nullptr;
+ }
mojo_filter->protocol_code = filter.protocolCode();
+ }
if (filter.hasSerialNumber())
mojo_filter->serial_number = filter.serialNumber();
return mojo_filter;
@@ -82,10 +112,8 @@ ScriptPromise USB::getDevices(ScriptState* script_state) {
}
if (!IsFeatureEnabled()) {
ExecutionContext* execution_context = ExecutionContext::From(script_state);
- if (execution_context && execution_context->IsDocument()) {
- ToDocument(execution_context)
- ->GetFrame()
- ->ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature::kUsb);
+ if (auto* document = DynamicTo<Document>(execution_context)) {
+ document->ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature::kUsb);
}
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
@@ -103,14 +131,14 @@ ScriptPromise USB::getDevices(ScriptState* script_state) {
ScriptPromise USB::requestDevice(ScriptState* script_state,
const USBDeviceRequestOptions& options) {
LocalFrame* frame = GetFrame();
- if (!frame) {
+ if (!frame || !frame->GetDocument()) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(DOMExceptionCode::kNotSupportedError));
}
- if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb,
- ReportOptions::kReportOnFailure)) {
+ if (!frame->GetDocument()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kUsb, ReportOptions::kReportOnFailure)) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
kFeaturePolicyBlocked));
@@ -118,7 +146,7 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
EnsureServiceConnection();
- if (!Frame::HasTransientUserActivation(frame)) {
+ if (!LocalFrame::HasTransientUserActivation(frame)) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
@@ -126,19 +154,26 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
"Must be handling a user gesture to show a permission request."));
}
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise promise = resolver->Promise();
Vector<UsbDeviceFilterPtr> filters;
if (options.hasFilters()) {
filters.ReserveCapacity(options.filters().size());
- for (const auto& filter : options.filters())
- filters.push_back(ConvertDeviceFilter(filter));
+ for (const auto& filter : options.filters()) {
+ UsbDeviceFilterPtr converted_filter =
+ ConvertDeviceFilter(filter, resolver);
+ if (!converted_filter)
+ return promise;
+ filters.push_back(std::move(converted_filter));
+ }
}
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ DCHECK(options.filters().size() == filters.size());
get_permission_requests_.insert(resolver);
service_->GetPermission(std::move(filters),
WTF::Bind(&USB::OnGetPermission, WrapPersistent(this),
WrapPersistent(resolver)));
- return resolver->Promise();
+ return promise;
}
ExecutionContext* USB::GetExecutionContext() const {
@@ -255,7 +290,7 @@ void USB::EnsureServiceConnection() {
DCHECK(!client_binding_.is_bound());
- device::mojom::blink::UsbDeviceManagerClientPtr client;
+ device::mojom::blink::UsbDeviceManagerClientAssociatedPtrInfo client;
client_binding_.Bind(mojo::MakeRequest(&client));
service_->SetClient(std::move(client));
}
@@ -277,9 +312,8 @@ bool USB::IsContextSupported() const {
}
bool USB::IsFeatureEnabled() const {
- ExecutionContext* context = GetExecutionContext();
- FeaturePolicy* policy = context->GetSecurityContext().GetFeaturePolicy();
- return policy->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb);
+ return GetExecutionContext()->GetSecurityContext().IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kUsb);
}
void USB::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h
index 9c871d920fd..768227ec3bd 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_H_
#include "device/usb/public/mojom/device_manager.mojom-blink.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/blink/public/mojom/usb/web_usb_service.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
@@ -84,7 +84,8 @@ class USB final : public EventTargetWithInlineData,
mojom::blink::WebUsbServicePtr service_;
HeapHashSet<Member<ScriptPromiseResolver>> get_devices_requests_;
HeapHashSet<Member<ScriptPromiseResolver>> get_permission_requests_;
- mojo::Binding<device::mojom::blink::UsbDeviceManagerClient> client_binding_;
+ mojo::AssociatedBinding<device::mojom::blink::UsbDeviceManagerClient>
+ client_binding_;
HeapHashMap<String, WeakMember<USBDevice>> device_cache_;
};
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
index ebcddcca82e..fb2799d19b7 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc
@@ -12,16 +12,16 @@ namespace blink {
USBAlternateInterface* USBAlternateInterface::Create(
const USBInterface* interface,
- size_t alternate_index) {
+ wtf_size_t alternate_index) {
return new USBAlternateInterface(interface, alternate_index);
}
USBAlternateInterface* USBAlternateInterface::Create(
const USBInterface* interface,
- size_t alternate_setting,
+ uint8_t alternate_setting,
ExceptionState& exception_state) {
const auto& alternates = interface->Info().alternates;
- for (size_t i = 0; i < alternates.size(); ++i) {
+ for (wtf_size_t i = 0; i < alternates.size(); ++i) {
if (alternates[i]->alternate_setting == alternate_setting)
return USBAlternateInterface::Create(interface, i);
}
@@ -30,7 +30,7 @@ USBAlternateInterface* USBAlternateInterface::Create(
}
USBAlternateInterface::USBAlternateInterface(const USBInterface* interface,
- size_t alternate_index)
+ wtf_size_t alternate_index)
: interface_(interface), alternate_index_(alternate_index) {
DCHECK(interface_);
DCHECK_LT(alternate_index_, interface_->Info().alternates.size());
@@ -46,7 +46,7 @@ USBAlternateInterface::Info() const {
HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const {
HeapVector<Member<USBEndpoint>> endpoints;
- for (size_t i = 0; i < Info().endpoints.size(); ++i)
+ for (wtf_size_t i = 0; i < Info().endpoints.size(); ++i)
endpoints.push_back(USBEndpoint::Create(this, i));
return endpoints;
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
index cb020d544a6..da8d3182551 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h
@@ -20,12 +20,12 @@ class USBAlternateInterface : public ScriptWrappable {
public:
static USBAlternateInterface* Create(const USBInterface*,
- size_t alternate_index);
+ wtf_size_t alternate_index);
static USBAlternateInterface* Create(const USBInterface*,
- size_t alternate_setting,
+ uint8_t alternate_setting,
ExceptionState&);
- USBAlternateInterface(const USBInterface*, size_t alternate_index);
+ USBAlternateInterface(const USBInterface*, wtf_size_t alternate_index);
const device::mojom::blink::UsbAlternateInterfaceInfo& Info() const;
@@ -40,7 +40,7 @@ class USBAlternateInterface : public ScriptWrappable {
private:
Member<const USBInterface> interface_;
- const size_t alternate_index_;
+ const wtf_size_t alternate_index_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
index 582ffe46995..cc21bf0ffd5 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc
@@ -12,15 +12,15 @@
namespace blink {
USBConfiguration* USBConfiguration::Create(const USBDevice* device,
- size_t configuration_index) {
+ wtf_size_t configuration_index) {
return new USBConfiguration(device, configuration_index);
}
USBConfiguration* USBConfiguration::Create(const USBDevice* device,
- size_t configuration_value,
+ uint8_t configuration_value,
ExceptionState& exception_state) {
const auto& configurations = device->Info().configurations;
- for (size_t i = 0; i < configurations.size(); ++i) {
+ for (wtf_size_t i = 0; i < configurations.size(); ++i) {
if (configurations[i]->configuration_value == configuration_value)
return new USBConfiguration(device, i);
}
@@ -29,7 +29,7 @@ USBConfiguration* USBConfiguration::Create(const USBDevice* device,
}
USBConfiguration::USBConfiguration(const USBDevice* device,
- size_t configuration_index)
+ wtf_size_t configuration_index)
: device_(device), configuration_index_(configuration_index) {
DCHECK(device_);
DCHECK_LT(configuration_index_, device_->Info().configurations.size());
@@ -39,7 +39,7 @@ const USBDevice* USBConfiguration::Device() const {
return device_;
}
-size_t USBConfiguration::Index() const {
+wtf_size_t USBConfiguration::Index() const {
return configuration_index_;
}
@@ -50,7 +50,7 @@ const device::mojom::blink::UsbConfigurationInfo& USBConfiguration::Info()
HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const {
HeapVector<Member<USBInterface>> interfaces;
- for (size_t i = 0; i < Info().interfaces.size(); ++i)
+ for (wtf_size_t i = 0; i < Info().interfaces.size(); ++i)
interfaces.push_back(USBInterface::Create(this, i));
return interfaces;
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
index c71bfea9f8c..c8ed6bc7063 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h
@@ -19,15 +19,16 @@ class USBConfiguration : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static USBConfiguration* Create(const USBDevice*, size_t configuration_index);
static USBConfiguration* Create(const USBDevice*,
- size_t configuration_value,
+ wtf_size_t configuration_index);
+ static USBConfiguration* Create(const USBDevice*,
+ uint8_t configuration_value,
ExceptionState&);
- USBConfiguration(const USBDevice*, size_t configuration_index);
+ USBConfiguration(const USBDevice*, wtf_size_t configuration_index);
const USBDevice* Device() const;
- size_t Index() const;
+ wtf_size_t Index() const;
const device::mojom::blink::UsbConfigurationInfo& Info() const;
uint8_t configurationValue() const { return Info().configuration_value; }
@@ -38,7 +39,7 @@ class USBConfiguration : public ScriptWrappable {
private:
Member<const USBDevice> device_;
- const size_t configuration_index_;
+ const wtf_size_t configuration_index_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
index f74584f3323..d46935c3fd0 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -116,13 +116,14 @@ USBDevice::USBDevice(UsbDeviceInfoPtr device_info,
device_(std::move(device)),
opened_(false),
device_state_change_in_progress_(false),
- configuration_index_(-1) {
+ configuration_index_(kNotFound) {
if (device_) {
device_.set_connection_error_handler(
WTF::Bind(&USBDevice::OnConnectionError, WrapWeakPersistent(this)));
}
- int configuration_index = FindConfigurationIndex(Info().active_configuration);
- if (configuration_index != -1)
+ wtf_size_t configuration_index =
+ FindConfigurationIndex(Info().active_configuration);
+ if (configuration_index != kNotFound)
OnConfigurationSelected(true /* success */, configuration_index);
}
@@ -132,27 +133,28 @@ USBDevice::~USBDevice() {
DCHECK(device_requests_.IsEmpty());
}
-bool USBDevice::IsInterfaceClaimed(size_t configuration_index,
- size_t interface_index) const {
- return configuration_index_ != -1 &&
- static_cast<size_t>(configuration_index_) == configuration_index &&
+bool USBDevice::IsInterfaceClaimed(wtf_size_t configuration_index,
+ wtf_size_t interface_index) const {
+ return configuration_index_ != kNotFound &&
+ configuration_index_ == configuration_index &&
claimed_interfaces_.Get(interface_index);
}
-size_t USBDevice::SelectedAlternateInterface(size_t interface_index) const {
+wtf_size_t USBDevice::SelectedAlternateInterface(
+ wtf_size_t interface_index) const {
return selected_alternates_[interface_index];
}
USBConfiguration* USBDevice::configuration() const {
- if (configuration_index_ != -1)
+ if (configuration_index_ != kNotFound)
return USBConfiguration::Create(this, configuration_index_);
return nullptr;
}
HeapVector<Member<USBConfiguration>> USBDevice::configurations() const {
- size_t num_configurations = Info().configurations.size();
+ wtf_size_t num_configurations = Info().configurations.size();
HeapVector<Member<USBConfiguration>> configurations(num_configurations);
- for (size_t i = 0; i < num_configurations; ++i)
+ for (wtf_size_t i = 0; i < num_configurations; ++i)
configurations[i] = USBConfiguration::Create(this, i);
return configurations;
}
@@ -198,8 +200,9 @@ ScriptPromise USBDevice::selectConfiguration(ScriptState* script_state,
resolver->Reject(DOMException::Create(
DOMExceptionCode::kInvalidStateError, kOpenRequired));
} else {
- int configuration_index = FindConfigurationIndex(configuration_value);
- if (configuration_index == -1) {
+ wtf_size_t configuration_index =
+ FindConfigurationIndex(configuration_value);
+ if (configuration_index == kNotFound) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
"The configuration value "
"provided is not supported by "
@@ -225,8 +228,8 @@ ScriptPromise USBDevice::claimInterface(ScriptState* script_state,
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
if (EnsureDeviceConfigured(resolver)) {
- int interface_index = FindInterfaceIndex(interface_number);
- if (interface_index == -1) {
+ wtf_size_t interface_index = FindInterfaceIndex(interface_number);
+ if (interface_index == kNotFound) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
kInterfaceNotFound));
} else if (interface_state_change_in_progress_.Get(interface_index)) {
@@ -261,8 +264,8 @@ ScriptPromise USBDevice::releaseInterface(ScriptState* script_state,
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
if (EnsureDeviceConfigured(resolver)) {
- int interface_index = FindInterfaceIndex(interface_number);
- if (interface_index == -1) {
+ wtf_size_t interface_index = FindInterfaceIndex(interface_number);
+ if (interface_index == kNotFound) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
"The interface number provided is "
"not supported by the device in "
@@ -295,11 +298,11 @@ ScriptPromise USBDevice::selectAlternateInterface(ScriptState* script_state,
ScriptPromise promise = resolver->Promise();
if (EnsureInterfaceClaimed(interface_number, resolver)) {
// TODO(reillyg): This is duplicated work.
- int interface_index = FindInterfaceIndex(interface_number);
- DCHECK_NE(interface_index, -1);
- int alternate_index =
+ wtf_size_t interface_index = FindInterfaceIndex(interface_number);
+ DCHECK_NE(interface_index, kNotFound);
+ wtf_size_t alternate_index =
FindAlternateIndex(interface_index, alternate_setting);
- if (alternate_index == -1) {
+ if (alternate_index == kNotFound) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
"The alternate setting provided is "
"not supported by the device in "
@@ -484,43 +487,44 @@ void USBDevice::Trace(blink::Visitor* visitor) {
ContextLifecycleObserver::Trace(visitor);
}
-int USBDevice::FindConfigurationIndex(uint8_t configuration_value) const {
+wtf_size_t USBDevice::FindConfigurationIndex(
+ uint8_t configuration_value) const {
const auto& configurations = Info().configurations;
- for (size_t i = 0; i < configurations.size(); ++i) {
+ for (wtf_size_t i = 0; i < configurations.size(); ++i) {
if (configurations[i]->configuration_value == configuration_value)
return i;
}
- return -1;
+ return kNotFound;
}
-int USBDevice::FindInterfaceIndex(uint8_t interface_number) const {
- DCHECK_NE(configuration_index_, -1);
+wtf_size_t USBDevice::FindInterfaceIndex(uint8_t interface_number) const {
+ DCHECK_NE(configuration_index_, kNotFound);
const auto& interfaces =
Info().configurations[configuration_index_]->interfaces;
- for (size_t i = 0; i < interfaces.size(); ++i) {
+ for (wtf_size_t i = 0; i < interfaces.size(); ++i) {
if (interfaces[i]->interface_number == interface_number)
return i;
}
- return -1;
+ return kNotFound;
}
-int USBDevice::FindAlternateIndex(size_t interface_index,
- uint8_t alternate_setting) const {
- DCHECK_NE(configuration_index_, -1);
+wtf_size_t USBDevice::FindAlternateIndex(uint32_t interface_index,
+ uint8_t alternate_setting) const {
+ DCHECK_NE(configuration_index_, kNotFound);
const auto& alternates = Info()
.configurations[configuration_index_]
->interfaces[interface_index]
->alternates;
- for (size_t i = 0; i < alternates.size(); ++i) {
+ for (wtf_size_t i = 0; i < alternates.size(); ++i) {
if (alternates[i]->alternate_setting == alternate_setting)
return i;
}
- return -1;
+ return kNotFound;
}
-bool USBDevice::IsProtectedInterfaceClass(int interface_index) const {
- DCHECK_NE(configuration_index_, -1);
- DCHECK_NE(interface_index, -1);
+bool USBDevice::IsProtectedInterfaceClass(wtf_size_t interface_index) const {
+ DCHECK_NE(configuration_index_, kNotFound);
+ DCHECK_NE(interface_index, kNotFound);
// USB Class Codes are defined by the USB-IF:
// http://www.usb.org/developers/defined_class
@@ -578,7 +582,7 @@ bool USBDevice::EnsureDeviceConfigured(ScriptPromiseResolver* resolver) const {
} else if (!opened_) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kInvalidStateError,
kOpenRequired));
- } else if (configuration_index_ == -1) {
+ } else if (configuration_index_ == kNotFound) {
resolver->Reject(
DOMException::Create(DOMExceptionCode::kInvalidStateError,
"The device must have a configuration selected."));
@@ -592,8 +596,8 @@ bool USBDevice::EnsureInterfaceClaimed(uint8_t interface_number,
ScriptPromiseResolver* resolver) const {
if (!EnsureDeviceConfigured(resolver))
return false;
- int interface_index = FindInterfaceIndex(interface_number);
- if (interface_index == -1) {
+ wtf_size_t interface_index = FindInterfaceIndex(interface_number);
+ if (interface_index == kNotFound) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
kInterfaceNotFound));
} else if (interface_state_change_in_progress_.Get(interface_index)) {
@@ -632,7 +636,7 @@ bool USBDevice::EnsureEndpointAvailable(bool in_transfer,
}
bool USBDevice::AnyInterfaceChangeInProgress() const {
- for (size_t i = 0; i < interface_state_change_in_progress_.size(); ++i) {
+ for (wtf_size_t i = 0; i < interface_state_change_in_progress_.size(); ++i) {
if (interface_state_change_in_progress_.QuickGet(i))
return true;
}
@@ -660,13 +664,13 @@ UsbControlTransferParamsPtr USBDevice::ConvertControlTransferParameters(
if (parameters.recipient() == "device") {
mojo_parameters->recipient = UsbControlTransferRecipient::DEVICE;
} else if (parameters.recipient() == "interface") {
- size_t interface_number = parameters.index() & 0xff;
+ uint8_t interface_number = parameters.index() & 0xff;
if (!EnsureInterfaceClaimed(interface_number, resolver))
return nullptr;
mojo_parameters->recipient = UsbControlTransferRecipient::INTERFACE;
} else if (parameters.recipient() == "endpoint") {
bool in_transfer = parameters.index() & 0x80;
- size_t endpoint_number = parameters.index() & 0x0f;
+ uint8_t endpoint_number = parameters.index() & 0x0f;
if (!EnsureEndpointAvailable(in_transfer, endpoint_number, resolver))
return nullptr;
mojo_parameters->recipient = UsbControlTransferRecipient::ENDPOINT;
@@ -685,7 +689,7 @@ UsbControlTransferParamsPtr USBDevice::ConvertControlTransferParameters(
return mojo_parameters;
}
-void USBDevice::SetEndpointsForInterface(size_t interface_index, bool set) {
+void USBDevice::SetEndpointsForInterface(wtf_size_t interface_index, bool set) {
const auto& configuration = *Info().configurations[configuration_index_];
const auto& interface = *configuration.interfaces[interface_index];
const auto& alternate =
@@ -744,7 +748,7 @@ void USBDevice::OnDeviceOpenedOrClosed(bool opened) {
device_state_change_in_progress_ = false;
}
-void USBDevice::AsyncSelectConfiguration(size_t configuration_index,
+void USBDevice::AsyncSelectConfiguration(wtf_size_t configuration_index,
ScriptPromiseResolver* resolver,
bool success) {
if (!MarkRequestComplete(resolver))
@@ -761,10 +765,10 @@ void USBDevice::AsyncSelectConfiguration(size_t configuration_index,
}
void USBDevice::OnConfigurationSelected(bool success,
- size_t configuration_index) {
+ wtf_size_t configuration_index) {
if (success) {
configuration_index_ = configuration_index;
- size_t num_interfaces =
+ wtf_size_t num_interfaces =
Info().configurations[configuration_index_]->interfaces.size();
claimed_interfaces_.ClearAll();
claimed_interfaces_.Resize(num_interfaces);
@@ -778,7 +782,7 @@ void USBDevice::OnConfigurationSelected(bool success,
device_state_change_in_progress_ = false;
}
-void USBDevice::AsyncClaimInterface(size_t interface_index,
+void USBDevice::AsyncClaimInterface(wtf_size_t interface_index,
ScriptPromiseResolver* resolver,
bool success) {
if (!MarkRequestComplete(resolver))
@@ -793,7 +797,7 @@ void USBDevice::AsyncClaimInterface(size_t interface_index,
}
}
-void USBDevice::AsyncReleaseInterface(size_t interface_index,
+void USBDevice::AsyncReleaseInterface(wtf_size_t interface_index,
ScriptPromiseResolver* resolver,
bool success) {
if (!MarkRequestComplete(resolver))
@@ -809,7 +813,7 @@ void USBDevice::AsyncReleaseInterface(size_t interface_index,
}
void USBDevice::OnInterfaceClaimedOrUnclaimed(bool claimed,
- size_t interface_index) {
+ wtf_size_t interface_index) {
if (claimed) {
claimed_interfaces_.Set(interface_index);
} else {
@@ -820,8 +824,8 @@ void USBDevice::OnInterfaceClaimedOrUnclaimed(bool claimed,
interface_state_change_in_progress_.Clear(interface_index);
}
-void USBDevice::AsyncSelectAlternateInterface(size_t interface_index,
- size_t alternate_index,
+void USBDevice::AsyncSelectAlternateInterface(wtf_size_t interface_index,
+ wtf_size_t alternate_index,
ScriptPromiseResolver* resolver,
bool success) {
if (!MarkRequestComplete(resolver))
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
index 41b611655fc..c106b4b8b86 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -40,9 +40,9 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
const device::mojom::blink::UsbDeviceInfo& Info() const {
return *device_info_;
}
- bool IsInterfaceClaimed(size_t configuration_index,
- size_t interface_index) const;
- size_t SelectedAlternateInterface(size_t interface_index) const;
+ bool IsInterfaceClaimed(wtf_size_t configuration_index,
+ wtf_size_t interface_index) const;
+ wtf_size_t SelectedAlternateInterface(wtf_size_t interface_index) const;
// USBDevice.idl
uint8_t usbVersionMajor() const { return Info().usb_version_major; }
@@ -105,11 +105,11 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
void Trace(blink::Visitor*) override;
private:
- int FindConfigurationIndex(uint8_t configuration_value) const;
- int FindInterfaceIndex(uint8_t interface_number) const;
- int FindAlternateIndex(size_t interface_index,
- uint8_t alternate_setting) const;
- bool IsProtectedInterfaceClass(int interface_index) const;
+ wtf_size_t FindConfigurationIndex(uint8_t configuration_value) const;
+ wtf_size_t FindInterfaceIndex(uint8_t interface_number) const;
+ wtf_size_t FindAlternateIndex(wtf_size_t interface_index,
+ uint8_t alternate_setting) const;
+ bool IsProtectedInterfaceClass(wtf_size_t interface_index) const;
bool EnsureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*) const;
bool EnsureDeviceConfigured(ScriptPromiseResolver*) const;
bool EnsureInterfaceClaimed(uint8_t interface_number,
@@ -121,25 +121,25 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
device::mojom::blink::UsbControlTransferParamsPtr
ConvertControlTransferParameters(const USBControlTransferParameters&,
ScriptPromiseResolver*) const;
- void SetEndpointsForInterface(size_t interface_index, bool set);
+ void SetEndpointsForInterface(wtf_size_t interface_index, bool set);
void AsyncOpen(ScriptPromiseResolver*,
device::mojom::blink::UsbOpenDeviceError);
void AsyncClose(ScriptPromiseResolver*);
void OnDeviceOpenedOrClosed(bool);
- void AsyncSelectConfiguration(size_t configuration_index,
+ void AsyncSelectConfiguration(wtf_size_t configuration_index,
ScriptPromiseResolver*,
bool success);
- void OnConfigurationSelected(bool success, size_t configuration_index);
- void AsyncClaimInterface(size_t interface_index,
+ void OnConfigurationSelected(bool success, wtf_size_t configuration_index);
+ void AsyncClaimInterface(wtf_size_t interface_index,
ScriptPromiseResolver*,
bool success);
- void AsyncReleaseInterface(size_t interface_index,
+ void AsyncReleaseInterface(wtf_size_t interface_index,
ScriptPromiseResolver*,
bool success);
- void OnInterfaceClaimedOrUnclaimed(bool claimed, size_t interface_index);
- void AsyncSelectAlternateInterface(size_t interface_index,
- size_t alternate_index,
+ void OnInterfaceClaimedOrUnclaimed(bool claimed, wtf_size_t interface_index);
+ void AsyncSelectAlternateInterface(wtf_size_t interface_index,
+ wtf_size_t alternate_index,
ScriptPromiseResolver*,
bool success);
void AsyncControlTransferIn(ScriptPromiseResolver*,
@@ -172,10 +172,10 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
HeapHashSet<Member<ScriptPromiseResolver>> device_requests_;
bool opened_;
bool device_state_change_in_progress_;
- int configuration_index_;
+ wtf_size_t configuration_index_;
WTF::BitVector claimed_interfaces_;
WTF::BitVector interface_state_change_in_progress_;
- WTF::Vector<size_t> selected_alternates_;
+ WTF::Vector<wtf_size_t> selected_alternates_;
WTF::BitVector in_endpoints_;
WTF::BitVector out_endpoints_;
};
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
index 0152b9a70d9..5a0043c1734 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc
@@ -45,19 +45,19 @@ String ConvertTypeToEnum(const UsbTransferType& type) {
} // namespace
USBEndpoint* USBEndpoint::Create(const USBAlternateInterface* alternate,
- size_t endpoint_index) {
+ wtf_size_t endpoint_index) {
return new USBEndpoint(alternate, endpoint_index);
}
USBEndpoint* USBEndpoint::Create(const USBAlternateInterface* alternate,
- size_t endpoint_number,
+ uint8_t endpoint_number,
const String& direction,
ExceptionState& exception_state) {
UsbTransferDirection mojo_direction = direction == "in"
? UsbTransferDirection::INBOUND
: UsbTransferDirection::OUTBOUND;
const auto& endpoints = alternate->Info().endpoints;
- for (size_t i = 0; i < endpoints.size(); ++i) {
+ for (wtf_size_t i = 0; i < endpoints.size(); ++i) {
const auto& endpoint = endpoints[i];
if (endpoint->endpoint_number == endpoint_number &&
endpoint->direction == mojo_direction)
@@ -69,7 +69,7 @@ USBEndpoint* USBEndpoint::Create(const USBAlternateInterface* alternate,
}
USBEndpoint::USBEndpoint(const USBAlternateInterface* alternate,
- size_t endpoint_index)
+ wtf_size_t endpoint_index)
: alternate_(alternate), endpoint_index_(endpoint_index) {
DCHECK(alternate_);
DCHECK_LT(endpoint_index_, alternate_->Info().endpoints.size());
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
index 7a4759047bb..663a1d4006f 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h
@@ -19,13 +19,13 @@ class USBEndpoint : public ScriptWrappable {
public:
static USBEndpoint* Create(const USBAlternateInterface*,
- size_t endpoint_index);
+ wtf_size_t endpoint_index);
static USBEndpoint* Create(const USBAlternateInterface*,
- size_t endpoint_number,
+ uint8_t endpoint_number,
const String& direction,
ExceptionState&);
- USBEndpoint(const USBAlternateInterface*, size_t endpoint_index);
+ USBEndpoint(const USBAlternateInterface*, wtf_size_t endpoint_index);
const device::mojom::blink::UsbEndpointInfo& Info() const;
@@ -38,7 +38,7 @@ class USBEndpoint : public ScriptWrappable {
private:
Member<const USBAlternateInterface> alternate_;
- const size_t endpoint_index_;
+ const wtf_size_t endpoint_index_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
index 4091c9a38f9..4193de72179 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc
@@ -13,16 +13,16 @@
namespace blink {
USBInterface* USBInterface::Create(const USBConfiguration* configuration,
- size_t interface_index) {
+ wtf_size_t interface_index) {
return new USBInterface(configuration->Device(), configuration->Index(),
interface_index);
}
USBInterface* USBInterface::Create(const USBConfiguration* configuration,
- size_t interface_number,
+ uint8_t interface_number,
ExceptionState& exception_state) {
const auto& interfaces = configuration->Info().interfaces;
- for (size_t i = 0; i < interfaces.size(); ++i) {
+ for (wtf_size_t i = 0; i < interfaces.size(); ++i) {
if (interfaces[i]->interface_number == interface_number)
return new USBInterface(configuration->Device(), configuration->Index(),
i);
@@ -32,8 +32,8 @@ USBInterface* USBInterface::Create(const USBConfiguration* configuration,
}
USBInterface::USBInterface(const USBDevice* device,
- size_t configuration_index,
- size_t interface_index)
+ wtf_size_t configuration_index,
+ wtf_size_t interface_index)
: device_(device),
configuration_index_(configuration_index),
interface_index_(interface_index) {
@@ -58,7 +58,7 @@ USBAlternateInterface* USBInterface::alternate() const {
HeapVector<Member<USBAlternateInterface>> USBInterface::alternates() const {
HeapVector<Member<USBAlternateInterface>> alternates;
- for (size_t i = 0; i < Info().alternates.size(); ++i)
+ for (wtf_size_t i = 0; i < Info().alternates.size(); ++i)
alternates.push_back(USBAlternateInterface::Create(this, i));
return alternates;
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
index 2bcb1ba7ee1..a8639a6cf41 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h
@@ -20,14 +20,15 @@ class USBInterface : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static USBInterface* Create(const USBConfiguration*, size_t interface_index);
static USBInterface* Create(const USBConfiguration*,
- size_t interface_number,
+ wtf_size_t interface_index);
+ static USBInterface* Create(const USBConfiguration*,
+ uint8_t interface_number,
ExceptionState&);
USBInterface(const USBDevice*,
- size_t configuration_index,
- size_t interface_index);
+ wtf_size_t configuration_index,
+ wtf_size_t interface_index);
const device::mojom::blink::UsbInterfaceInfo& Info() const;
@@ -40,8 +41,8 @@ class USBInterface : public ScriptWrappable {
private:
Member<const USBDevice> device_;
- const size_t configuration_index_;
- const size_t interface_index_;
+ const wtf_size_t configuration_index_;
+ const wtf_size_t interface_index_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.cc b/chromium/third_party/blink/renderer/modules/xr/xr.cc
index 94d75fb3781..6115eafb100 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr.cc
@@ -6,6 +6,7 @@
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -14,7 +15,6 @@
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_device.h"
-#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
namespace blink {
namespace {
@@ -73,8 +73,10 @@ ScriptPromise XR::requestDevice(ScriptState* script_state) {
did_log_requestDevice_ = true;
}
- if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebVr)) {
- // Only allow the call to be made if the appropraite feature policy is in
+ if (!frame->GetDocument()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kWebVr,
+ ReportOptions::kReportOnFailure)) {
+ // Only allow the call to be made if the appropriate feature policy is in
// place.
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.cc b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.cc
index 0d4bd264f26..b00c970e42b 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_coordinate_system.h"
+#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
@@ -29,9 +30,18 @@ DOMFloat32Array* XRCoordinateSystem::getTransformTo(
return nullptr;
}
+ExecutionContext* XRCoordinateSystem::GetExecutionContext() const {
+ return session()->GetExecutionContext();
+}
+
+const AtomicString& XRCoordinateSystem::InterfaceName() const {
+ return EventTargetNames::XRCoordinateSystem;
+}
+
void XRCoordinateSystem::Trace(blink::Visitor* visitor) {
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
+ EventTargetWithInlineData::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.h b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.h
index 265f4c61e5b..9ba5d6ece16 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_COORDINATE_SYSTEM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_COORDINATE_SYSTEM_H_
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -15,7 +16,7 @@ namespace blink {
class TransformationMatrix;
class XRSession;
-class XRCoordinateSystem : public ScriptWrappable {
+class XRCoordinateSystem : public EventTargetWithInlineData {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -24,7 +25,11 @@ class XRCoordinateSystem : public ScriptWrappable {
DOMFloat32Array* getTransformTo(XRCoordinateSystem*) const;
- XRSession* session() { return session_; }
+ XRSession* session() const { return session_; }
+
+ // EventTarget overrides.
+ ExecutionContext* GetExecutionContext() const override;
+ const AtomicString& InterfaceName() const override;
virtual std::unique_ptr<TransformationMatrix> TransformBasePose(
const TransformationMatrix& base_pose) = 0;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
index 42e5a9b1029..668360f27a0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
@@ -7,6 +7,6 @@
SecureContext,
Exposed=Window,
OriginTrialEnabled=WebXR
-] interface XRCoordinateSystem {
+] interface XRCoordinateSystem : EventTarget {
Float32Array? getTransformTo(XRCoordinateSystem other);
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device.cc b/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
index 92cd3cb2d44..a2a9d57ffcf 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -97,7 +97,7 @@ int64_t XRDevice::GetSourceId() const {
ScriptPromise XRDevice::requestSession(
ScriptState* script_state,
const XRSessionCreationOptions& options) {
- Document* doc = ToDocumentOrNull(ExecutionContext::From(script_state));
+ Document* doc = To<Document>(ExecutionContext::From(script_state));
if (options.immersive() && !did_log_request_immersive_session_ && doc) {
ukm::builders::XR_WebXR(GetSourceId())
@@ -117,7 +117,7 @@ ScriptPromise XRDevice::requestSession(
// TODO(ijamardo): Should we just exit if there is not document?
bool has_user_activation =
- Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr);
+ LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr);
// Check if the current page state prevents the requested session from being
// created.
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
index b985bd429f0..fa26356ef1c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/modules/xr/xr.h"
#include "third_party/blink/renderer/modules/xr/xr_device.h"
#include "third_party/blink/renderer/modules/xr/xr_presentation_context.h"
@@ -286,8 +287,12 @@ void XRFrameProvider::OnImmersiveFrameData(
// between frames. Executing mojo tasks back to back within the same
// execution context caused extreme input delay due to processing
// multiple frames without yielding, see crbug.com/701444.
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
+ //
+ // Used kInternalMedia since 1) this is not spec-ed and 2) this is media
+ // related then tasks should not be throttled or frozen in background tabs.
+ frame->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
WrapWeakPersistent(this), nullptr, high_res_now_ms));
}
@@ -301,8 +306,13 @@ void XRFrameProvider::OnNonImmersiveVSync(double high_res_now_ms) {
if (immersive_session_)
return;
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
+ LocalFrame* frame = device_->xr()->GetFrame();
+ if (!frame)
+ return;
+
+ frame->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
WrapWeakPersistent(this), nullptr, high_res_now_ms));
}
@@ -340,8 +350,9 @@ void XRFrameProvider::OnNonImmersiveFrameData(
.InMillisecondsF();
if (HasARSession()) {
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
+ frame->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
WrapWeakPersistent(this), std::move(frame_data),
high_res_now_ms));
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
index 6dd1aeaa952..84a957914b0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc
@@ -15,6 +15,8 @@ XRLayer::XRLayer(XRSession* session, XRLayerType layer_type)
void XRLayer::OnFrameStart(const base::Optional<gpu::MailboxHolder>&) {}
void XRLayer::OnFrameEnd() {}
void XRLayer::OnResize() {}
+void XRLayer::HandleBackgroundImage(const gpu::MailboxHolder&, const IntSize&) {
+}
void XRLayer::Trace(blink::Visitor* visitor) {
visitor->Trace(session_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
index 4150d74ef51..708ecb758d2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h
@@ -29,6 +29,10 @@ class XRLayer : public ScriptWrappable {
virtual void OnFrameEnd();
virtual void OnResize();
+ // Called from XRSession::OnFrame handler. Params are background texture
+ // mailbox holder and its size respectively.
+ virtual void HandleBackgroundImage(const gpu::MailboxHolder&, const IntSize&);
+
void Trace(blink::Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
index 08fdc3abdb5..d2e7b43e2b2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -249,7 +249,7 @@ void XRSession::cancelAnimationFrame(int id) {
}
HeapVector<Member<XRInputSource>> XRSession::getInputSources() const {
- Document* doc = ToDocumentOrNull(GetExecutionContext());
+ Document* doc = To<Document>(GetExecutionContext());
if (!did_log_getInputSources_ && doc) {
ukm::builders::XR_WebXR(device_->GetSourceId())
.SetDidGetXRInputSources(1)
@@ -492,10 +492,8 @@ void XRSession::OnFrame(
// If using a background image, the caller must provide its pixel size
// also. The source size can differ from the current drawing buffer size.
DCHECK(background_size);
- // TODO(https://crbug.com/837509): Remove this static_cast.
- XRWebGLLayer* webgl_layer = static_cast<XRWebGLLayer*>(frame_base_layer);
- webgl_layer->OverwriteColorBufferFromMailboxTexture(
- background_mailbox_holder.value(), background_size.value());
+ frame_base_layer->HandleBackgroundImage(background_mailbox_holder.value(),
+ background_size.value());
}
// Resolve the queued requestAnimationFrame callbacks. All XR rendering will
@@ -512,7 +510,7 @@ void XRSession::OnFrame(
}
void XRSession::LogGetPose() const {
- Document* doc = ToDocumentOrNull(GetExecutionContext());
+ Document* doc = To<Document>(GetExecutionContext());
if (!did_log_getDevicePose_ && doc) {
did_log_getDevicePose_ = true;
@@ -633,7 +631,7 @@ void XRSession::OnSelectEnd(XRInputSource* input_source) {
return;
std::unique_ptr<UserGestureIndicator> gesture_indicator =
- Frame::NotifyUserActivation(frame);
+ LocalFrame::NotifyUserActivation(frame);
XRInputSourceEvent* event =
CreateInputSourceEvent(EventTypeNames::selectend, input_source);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index be53fae2a05..99f98b4a820 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -311,6 +311,12 @@ void XRWebGLLayer::OnResize() {
viewports_dirty_ = true;
}
+void XRWebGLLayer::HandleBackgroundImage(
+ const gpu::MailboxHolder& mailbox_holder,
+ const IntSize& size) {
+ OverwriteColorBufferFromMailboxTexture(mailbox_holder, size);
+}
+
scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage(
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
return drawing_buffer_->TransferToStaticBitmapImage(out_release_callback);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
index 7616c7ce1ae..6368b919df4 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
@@ -44,10 +44,8 @@ class XRWebGLLayer final : public XRLayer,
WebGLRenderingContextOrWebGL2RenderingContext&) const;
WebGLFramebuffer* framebuffer() const { return framebuffer_; }
- unsigned long framebufferWidth() const {
- return drawing_buffer_->size().Width();
- }
- unsigned long framebufferHeight() const {
+ uint32_t framebufferWidth() const { return drawing_buffer_->size().Width(); }
+ uint32_t framebufferHeight() const {
return drawing_buffer_->size().Height();
}
@@ -69,6 +67,8 @@ class XRWebGLLayer final : public XRLayer,
void OnFrameStart(const base::Optional<gpu::MailboxHolder>&) override;
void OnFrameEnd() override;
void OnResize() override;
+ void HandleBackgroundImage(const gpu::MailboxHolder&,
+ const IntSize&) override;
void OverwriteColorBufferFromMailboxTexture(const gpu::MailboxHolder&,
const IntSize& size);