summaryrefslogtreecommitdiff
path: root/chromium/content/renderer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-08-01 12:59:39 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-08-04 12:40:43 +0000
commit28b1110370900897ab652cb420c371fab8857ad4 (patch)
tree41b32127d23b0df4f2add2a27e12dc87bddb260e /chromium/content/renderer
parent399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (diff)
downloadqtwebengine-chromium-28b1110370900897ab652cb420c371fab8857ad4.tar.gz
BASELINE: Update Chromium to 53.0.2785.41
Also adds a few extra files for extensions. Change-Id: Iccdd55d98660903331cf8b7b29188da781830af4 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/content/renderer')
-rw-r--r--chromium/content/renderer/BUILD.gn30
-rw-r--r--chromium/content/renderer/DEPS5
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc34
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.h2
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.cc68
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.h2
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.cc (renamed from chromium/content/renderer/accessibility/renderer_accessibility.cc)126
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.h (renamed from chromium/content/renderer/accessibility/renderer_accessibility.h)35
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc (renamed from chromium/content/renderer/accessibility/renderer_accessibility_browsertest.cc)58
-rw-r--r--chromium/content/renderer/android/disambiguation_popup_helper.cc29
-rw-r--r--chromium/content/renderer/android/renderer_date_time_picker.cc4
-rw-r--r--chromium/content/renderer/android/renderer_date_time_picker.h1
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.cc79
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.h60
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_filter.cc81
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_filter.h22
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_output_surface.cc45
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_output_surface.h11
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy.cc121
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy.h49
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_registry.h7
-rw-r--r--chromium/content/renderer/background_sync/background_sync_client_impl.h2
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_dispatcher.cc145
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_dispatcher.h84
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_message_filter.cc37
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_message_filter.h31
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_type_converters.cc60
-rw-r--r--chromium/content/renderer/bluetooth/bluetooth_type_converters.h43
-rw-r--r--chromium/content/renderer/bluetooth/web_bluetooth_impl.cc98
-rw-r--r--chromium/content/renderer/bluetooth/web_bluetooth_impl.h33
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.cc2
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.h2
-rw-r--r--chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc12
-rw-r--r--chromium/content/renderer/categorized_worker_pool.cc (renamed from chromium/content/renderer/raster_worker_pool.cc)92
-rw-r--r--chromium/content/renderer/categorized_worker_pool.h (renamed from chromium/content/renderer/raster_worker_pool.h)34
-rw-r--r--chromium/content/renderer/categorized_worker_pool_unittest.cc122
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.cc12
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.h12
-rw-r--r--chromium/content/renderer/devtools/devtools_agent.cc9
-rw-r--r--chromium/content/renderer/devtools/devtools_agent.h1
-rw-r--r--chromium/content/renderer/devtools/devtools_agent_filter.cc12
-rw-r--r--chromium/content/renderer/devtools/devtools_client.cc4
-rw-r--r--chromium/content/renderer/devtools/devtools_client.h1
-rw-r--r--chromium/content/renderer/devtools/render_widget_screen_metrics_emulator.cc2
-rw-r--r--chromium/content/renderer/devtools/v8_sampling_profiler.cc4
-rw-r--r--chromium/content/renderer/devtools/v8_sampling_profiler_browsertest.cc11
-rw-r--r--chromium/content/renderer/dom_automation_controller.cc4
-rw-r--r--chromium/content/renderer/dom_serializer_browsertest.cc3
-rw-r--r--chromium/content/renderer/external_popup_menu.cc6
-rw-r--r--chromium/content/renderer/external_popup_menu.h6
-rw-r--r--chromium/content/renderer/external_popup_menu_browsertest.cc16
-rw-r--r--chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc2
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.cc3
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.h3
-rw-r--r--chromium/content/renderer/frame_blame_context.cc2
-rw-r--r--chromium/content/renderer/gamepad_shared_memory_reader.cc1
-rw-r--r--chromium/content/renderer/gpu/compositor_dependencies.h2
-rw-r--r--chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc46
-rw-r--r--chromium/content/renderer/gpu/compositor_external_begin_frame_source.h13
-rw-r--r--chromium/content/renderer/gpu/compositor_forwarding_message_filter.cc1
-rw-r--r--chromium/content/renderer/gpu/compositor_output_surface.cc133
-rw-r--r--chromium/content/renderer/gpu/compositor_output_surface.h40
-rw-r--r--chromium/content/renderer/gpu/delegated_compositor_output_surface.cc28
-rw-r--r--chromium/content/renderer/gpu/delegated_compositor_output_surface.h31
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.cc4
-rw-r--r--chromium/content/renderer/gpu/mailbox_output_surface.cc239
-rw-r--r--chromium/content/renderer/gpu/mailbox_output_surface.h80
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise.cc17
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor.cc431
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor.h25
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor_delegate.h6
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor_unittest.cc292
-rw-r--r--chromium/content/renderer/history_controller.cc33
-rw-r--r--chromium/content/renderer/history_controller.h10
-rw-r--r--chromium/content/renderer/history_entry.cc6
-rw-r--r--chromium/content/renderer/history_serialization.cc75
-rw-r--r--chromium/content/renderer/idle_user_detector.cc4
-rw-r--r--chromium/content/renderer/idle_user_detector.h1
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_impl.cc22
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_impl.h5
-rw-r--r--chromium/content/renderer/input/input_event_filter.cc7
-rw-r--r--chromium/content/renderer/input/input_event_filter_unittest.cc58
-rw-r--r--chromium/content/renderer/input/input_handler_manager.cc43
-rw-r--r--chromium/content/renderer/input/input_handler_manager.h11
-rw-r--r--chromium/content/renderer/input/input_handler_wrapper.cc5
-rw-r--r--chromium/content/renderer/input/input_handler_wrapper.h3
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler.cc20
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler_delegate.h7
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_dispatcher.cc4
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_dispatcher.h3
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_value_converter.cc31
-rw-r--r--chromium/content/renderer/java/gin_java_bridge_value_converter.h8
-rw-r--r--chromium/content/renderer/layout_test_dependencies.h38
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.cc4
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.h3
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.cc109
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.h6
-rw-r--r--chromium/content/renderer/manifest/manifest_parser_unittest.cc166
-rw-r--r--chromium/content/renderer/media/DEPS2
-rw-r--r--chromium/content/renderer/media/android/media_info_loader_unittest.cc5
-rw-r--r--chromium/content/renderer/media/android/renderer_media_player_manager.cc4
-rw-r--r--chromium/content/renderer/media/android/renderer_media_player_manager.h3
-rw-r--r--chromium/content/renderer/media/android/renderer_media_session_manager.cc4
-rw-r--r--chromium/content/renderer/media/android/renderer_media_session_manager.h3
-rw-r--r--chromium/content/renderer/media/android/renderer_surface_view_manager.cc11
-rw-r--r--chromium/content/renderer/media/android/renderer_surface_view_manager.h3
-rw-r--r--chromium/content/renderer/media/android/webmediaplayer_android.cc16
-rw-r--r--chromium/content/renderer/media/audio_device_factory.cc51
-rw-r--r--chromium/content/renderer/media/audio_device_factory.h12
-rw-r--r--chromium/content/renderer/media/audio_renderer_mixer_manager.cc216
-rw-r--r--chromium/content/renderer/media/audio_renderer_mixer_manager.h83
-rw-r--r--chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc604
-rw-r--r--chromium/content/renderer/media/audio_renderer_sink_cache.h62
-rw-r--r--chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc253
-rw-r--r--chromium/content/renderer/media/audio_renderer_sink_cache_impl.h110
-rw-r--r--chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc374
-rw-r--r--chromium/content/renderer/media/audio_track_recorder.cc21
-rw-r--r--chromium/content/renderer/media/canvas_capture_handler.cc3
-rw-r--r--chromium/content/renderer/media/canvas_capture_handler.h4
-rw-r--r--chromium/content/renderer/media/canvas_capture_handler_unittest.cc2
-rw-r--r--chromium/content/renderer/media/cdm/renderer_cdm_manager.cc4
-rw-r--r--chromium/content/renderer/media/cdm/renderer_cdm_manager.h3
-rw-r--r--chromium/content/renderer/media/gpu/OWNERS2
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_decoder.cc (renamed from chromium/content/renderer/media/rtc_video_decoder.cc)41
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_decoder.h (renamed from chromium/content/renderer/media/rtc_video_decoder.h)13
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_decoder_factory.cc (renamed from chromium/content/renderer/media/rtc_video_decoder_factory.cc)4
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_decoder_factory.h (renamed from chromium/content/renderer/media/rtc_video_decoder_factory.h)6
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_decoder_unittest.cc (renamed from chromium/content/renderer/media/rtc_video_decoder_unittest.cc)20
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder.cc (renamed from chromium/content/renderer/media/rtc_video_encoder.cc)49
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder.h (renamed from chromium/content/renderer/media/rtc_video_encoder.h)6
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder_factory.cc (renamed from chromium/content/renderer/media/rtc_video_encoder_factory.cc)4
-rw-r--r--chromium/content/renderer/media/gpu/rtc_video_encoder_factory.h (renamed from chromium/content/renderer/media/rtc_video_encoder_factory.h)6
-rw-r--r--chromium/content/renderer/media/html_audio_element_capturer_source.cc90
-rw-r--r--chromium/content/renderer/media/html_audio_element_capturer_source.h63
-rw-r--r--chromium/content/renderer/media/html_audio_element_capturer_source_unittest.cc154
-rw-r--r--chromium/content/renderer/media/html_video_element_capturer_source.cc30
-rw-r--r--chromium/content/renderer/media/html_video_element_capturer_source.h7
-rw-r--r--chromium/content/renderer/media/image_capture_frame_grabber.cc2
-rw-r--r--chromium/content/renderer/media/media_interface_provider.cc3
-rw-r--r--chromium/content/renderer/media/media_permission_dispatcher.cc2
-rw-r--r--chromium/content/renderer/media/media_recorder_handler.cc7
-rw-r--r--chromium/content/renderer/media/media_stream_audio_deliverer.h2
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor.cc33
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor.h18
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor_options.cc86
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor_options.h31
-rw-r--r--chromium/content/renderer/media/media_stream_audio_processor_unittest.cc47
-rw-r--r--chromium/content/renderer/media/media_stream_audio_source.cc2
-rw-r--r--chromium/content/renderer/media/media_stream_audio_track.cc8
-rw-r--r--chromium/content/renderer/media/media_stream_audio_track.h2
-rw-r--r--chromium/content/renderer/media/media_stream_audio_unittest.cc7
-rw-r--r--chromium/content/renderer/media/media_stream_center.cc13
-rw-r--r--chromium/content/renderer/media/media_stream_renderer_factory_impl.cc8
-rw-r--r--chromium/content/renderer/media/media_stream_renderer_factory_impl.h4
-rw-r--r--chromium/content/renderer/media/media_stream_source.cc14
-rw-r--r--chromium/content/renderer/media/media_stream_source.h5
-rw-r--r--chromium/content/renderer/media/media_stream_track.cc2
-rw-r--r--chromium/content/renderer/media/media_stream_track.h5
-rw-r--r--chromium/content/renderer/media/media_stream_video_capturer_source.h3
-rw-r--r--chromium/content/renderer/media/media_stream_video_renderer_sink.cc2
-rw-r--r--chromium/content/renderer/media/media_stream_video_renderer_sink.h23
-rw-r--r--chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc2
-rw-r--r--chromium/content/renderer/media/media_stream_video_source.cc30
-rw-r--r--chromium/content/renderer/media/media_stream_video_source.h14
-rw-r--r--chromium/content/renderer/media/media_stream_video_source_unittest.cc22
-rw-r--r--chromium/content/renderer/media/media_stream_video_track.cc22
-rw-r--r--chromium/content/renderer/media/media_stream_video_track.h1
-rw-r--r--chromium/content/renderer/media/midi_dispatcher.cc14
-rw-r--r--chromium/content/renderer/media/midi_dispatcher.h3
-rw-r--r--chromium/content/renderer/media/mock_media_stream_registry.cc2
-rw-r--r--chromium/content/renderer/media/peer_connection_identity_store.h2
-rw-r--r--chromium/content/renderer/media/pepper_to_video_track_adapter.cc2
-rw-r--r--chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc2
-rw-r--r--chromium/content/renderer/media/remote_media_stream_impl.cc2
-rw-r--r--chromium/content/renderer/media/render_media_log.cc18
-rw-r--r--chromium/content/renderer/media/render_media_log.h7
-rw-r--r--chromium/content/renderer/media/render_media_log_unittest.cc8
-rw-r--r--chromium/content/renderer/media/renderer_webaudiodevice_impl.cc2
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc4
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.h1
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc40
-rw-r--r--chromium/content/renderer/media/rtc_certificate_generator.cc151
-rw-r--r--chromium/content/renderer/media/rtc_certificate_generator.h6
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler.cc39
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler.h2
-rw-r--r--chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc50
-rw-r--r--chromium/content/renderer/media/speech_recognition_audio_sink.cc2
-rw-r--r--chromium/content/renderer/media/speech_recognition_audio_sink.h2
-rw-r--r--chromium/content/renderer/media/track_audio_renderer.cc4
-rw-r--r--chromium/content/renderer/media/track_audio_renderer.h2
-rw-r--r--chromium/content/renderer/media/user_media_client_impl.cc4
-rw-r--r--chromium/content/renderer/media/user_media_client_impl.h3
-rw-r--r--chromium/content/renderer/media/video_capture_impl.cc46
-rw-r--r--chromium/content/renderer/media/video_capture_impl.h20
-rw-r--r--chromium/content/renderer/media/video_capture_impl_unittest.cc14
-rw-r--r--chromium/content/renderer/media/video_capture_message_filter.h15
-rw-r--r--chromium/content/renderer/media/video_capture_message_filter_unittest.cc8
-rw-r--r--chromium/content/renderer/media/video_track_recorder.cc358
-rw-r--r--chromium/content/renderer/media/video_track_recorder.h2
-rw-r--r--chromium/content/renderer/media/video_track_recorder_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms.cc6
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms.h14
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms_unittest.cc80
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc37
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc10
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc47
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h3
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.h1
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc35
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.h8
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_impl.cc9
-rw-r--r--chromium/content/renderer/media/webrtc_audio_device_impl.h7
-rw-r--r--chromium/content/renderer/media/webrtc_audio_renderer.cc49
-rw-r--r--chromium/content/renderer/media/webrtc_audio_renderer.h8
-rw-r--r--chromium/content/renderer/media/webrtc_local_audio_source_provider.cc4
-rw-r--r--chromium/content/renderer/media/webrtc_local_audio_source_provider.h2
-rw-r--r--chromium/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc2
-rw-r--r--chromium/content/renderer/mojo/blink_service_registry_impl.cc23
-rw-r--r--chromium/content/renderer/mojo/blink_service_registry_impl.h21
-rw-r--r--chromium/content/renderer/mojo/interface_provider_js_wrapper.cc112
-rw-r--r--chromium/content/renderer/mojo/interface_provider_js_wrapper.h75
-rw-r--r--chromium/content/renderer/mojo/service_registry_js_wrapper.cc115
-rw-r--r--chromium/content/renderer/mojo/service_registry_js_wrapper.h72
-rw-r--r--chromium/content/renderer/mojo_bindings_controller.cc4
-rw-r--r--chromium/content/renderer/mojo_bindings_controller.h1
-rw-r--r--chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc45
-rw-r--r--chromium/content/renderer/mus/BUILD.gn4
-rw-r--r--chromium/content/renderer/mus/compositor_mus_connection.cc14
-rw-r--r--chromium/content/renderer/mus/compositor_mus_connection.h14
-rw-r--r--chromium/content/renderer/mus/compositor_mus_connection_unittest.cc20
-rw-r--r--chromium/content/renderer/mus/render_widget_mus_connection.cc22
-rw-r--r--chromium/content/renderer/mus/render_widget_mus_connection.h3
-rw-r--r--chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc13
-rw-r--r--chromium/content/renderer/notification_permission_dispatcher.cc11
-rw-r--r--chromium/content/renderer/notification_permission_dispatcher.h3
-rw-r--r--chromium/content/renderer/p2p/filtering_network_manager.cc42
-rw-r--r--chromium/content/renderer/p2p/filtering_network_manager.h12
-rw-r--r--chromium/content/renderer/p2p/port_allocator.cc21
-rw-r--r--chromium/content/renderer/p2p/port_allocator.h20
-rw-r--r--chromium/content/renderer/pepper/message_channel.cc9
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc8
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.h1
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_controller.cc77
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_controller.h57
-rw-r--r--chromium/content/renderer/pepper/pepper_browser_connection.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_browser_connection.h3
-rw-r--r--chromium/content/renderer/pepper/pepper_compositor_host.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host.cc7
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc21
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.h1
-rw-r--r--chromium/content/renderer/pepper/pepper_media_device_manager.cc21
-rw-r--r--chromium/content/renderer/pepper/pepper_media_device_manager.h3
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output.cc17
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output.h5
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc147
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.h71
-rw-r--r--chromium/content/renderer/pepper/pepper_url_loader_host.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_video_decoder_host.cc6
-rw-r--r--chromium/content/renderer/pepper/pepper_video_decoder_host.h1
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.cc10
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.h3
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.cc18
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.h2
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper.cc12
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper.h1
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc4
-rw-r--r--chromium/content/renderer/pepper/ppb_audio_impl.cc26
-rw-r--r--chromium/content/renderer/pepper/ppb_audio_impl.h2
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc71
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.h21
-rw-r--r--chromium/content/renderer/pepper/ppb_video_decoder_impl.cc1
-rw-r--r--chromium/content/renderer/pepper/ppb_video_decoder_impl.h1
-rw-r--r--chromium/content/renderer/pepper/video_encoder_shim.cc3
-rw-r--r--chromium/content/renderer/presentation/presentation_dispatcher.cc10
-rw-r--r--chromium/content/renderer/presentation/presentation_dispatcher.h1
-rw-r--r--chromium/content/renderer/push_messaging/push_messaging_dispatcher.cc4
-rw-r--r--chromium/content/renderer/push_messaging/push_messaging_dispatcher.h3
-rw-r--r--chromium/content/renderer/raster_worker_pool_unittest.cc120
-rw-r--r--chromium/content/renderer/render_frame_impl.cc858
-rw-r--r--chromium/content/renderer/render_frame_impl.h123
-rw-r--r--chromium/content/renderer/render_frame_impl_browsertest.cc51
-rw-r--r--chromium/content/renderer/render_frame_proxy.cc29
-rw-r--r--chromium/content/renderer/render_frame_proxy.h8
-rw-r--r--chromium/content/renderer/render_thread_impl.cc361
-rw-r--r--chromium/content/renderer/render_thread_impl.h78
-rw-r--r--chromium/content/renderer/render_view_browsertest.cc119
-rw-r--r--chromium/content/renderer/render_view_impl.cc374
-rw-r--r--chromium/content/renderer/render_view_impl.h58
-rw-r--r--chromium/content/renderer/render_view_mouse_lock_dispatcher.h40
-rw-r--r--chromium/content/renderer/render_widget.cc208
-rw-r--r--chromium/content/renderer/render_widget.h30
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.cc3
-rw-r--r--chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc (renamed from chromium/content/renderer/render_view_mouse_lock_dispatcher.cc)35
-rw-r--r--chromium/content/renderer/render_widget_mouse_lock_dispatcher.h42
-rw-r--r--chromium/content/renderer/render_widget_unittest.cc13
-rw-r--r--chromium/content/renderer/renderer.sb12
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.cc92
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.h14
-rw-r--r--chromium/content/renderer/renderer_main.cc6
-rw-r--r--chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc4
-rw-r--r--chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.h1
-rw-r--r--chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc5
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.cc74
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.h24
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_util.cc10
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_util.h4
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc13
-rw-r--r--chromium/content/renderer/shared_worker_repository.cc4
-rw-r--r--chromium/content/renderer/shared_worker_repository.h3
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.cc4
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.h1
-rw-r--r--chromium/content/renderer/stats_collection_observer.cc4
-rw-r--r--chromium/content/renderer/stats_collection_observer.h3
-rw-r--r--chromium/content/renderer/text_input_client_observer.cc4
-rw-r--r--chromium/content/renderer/text_input_client_observer.h3
-rw-r--r--chromium/content/renderer/visual_state_browsertest.cc3
-rw-r--r--chromium/content/renderer/web_ui_extension.cc11
-rw-r--r--chromium/content/renderer/web_ui_extension_data.cc4
-rw-r--r--chromium/content/renderer/web_ui_extension_data.h1
321 files changed, 7052 insertions, 4912 deletions
diff --git a/chromium/content/renderer/BUILD.gn b/chromium/content/renderer/BUILD.gn
index 13138ab148a..3f9286e2144 100644
--- a/chromium/content/renderer/BUILD.gn
+++ b/chromium/content/renderer/BUILD.gn
@@ -7,6 +7,7 @@ import("//build/config/ui.gni")
import("//content/renderer/renderer.gni")
import("//media/media_options.gni")
import("//third_party/webrtc/build/webrtc.gni")
+import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
source_set("renderer") {
# Only the public target should depend on this. All other targets (even
@@ -51,19 +52,19 @@ source_set("renderer") {
"//device/bluetooth",
"//device/usb/public/interfaces",
"//device/vibration:mojo_bindings",
+ "//device/vr:mojo_bindings",
"//gin",
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
- "//ipc/mojo",
"//jingle:jingle_glue",
"//media",
"//media/blink",
+ "//media/capture",
"//media/gpu",
"//media/gpu/ipc/client",
"//media/gpu/ipc/common",
"//media/midi",
"//mojo/common",
- "//mojo/converters/geometry",
"//mojo/edk/js",
"//mojo/public/cpp/bindings",
"//mojo/public/js",
@@ -72,7 +73,6 @@ source_set("renderer") {
"//services/shell/public/cpp",
"//services/shell/public/interfaces",
"//skia",
- "//skia/public",
"//storage/common",
"//third_party/WebKit/public:blink",
"//third_party/WebKit/public:mojo_bindings",
@@ -89,6 +89,7 @@ source_set("renderer") {
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
"//ui/events/blink",
+ "//ui/gfx/geometry/mojo",
"//ui/gl",
"//ui/native_theme",
"//ui/surface",
@@ -99,25 +100,24 @@ source_set("renderer") {
if (use_aura) {
public_deps += [ "//content/renderer/mus" ]
allow_circular_includes_from += [ "//content/renderer/mus" ]
+ deps += [ "//components/mus/common:mus_common" ]
}
- if (is_mac) {
- sources -= [
- "webscrollbarbehavior_impl_gtkoraura.cc",
- "webscrollbarbehavior_impl_gtkoraura.h",
- ]
+ if (use_external_popup_menu) {
sources += [
"external_popup_menu.cc",
"external_popup_menu.h",
]
}
- if (is_android) {
- sources += [
- "external_popup_menu.cc",
- "external_popup_menu.h",
+ if (is_mac) {
+ sources -= [
+ "webscrollbarbehavior_impl_gtkoraura.cc",
+ "webscrollbarbehavior_impl_gtkoraura.h",
]
+ }
+ if (is_android) {
# Add back the Linux file which Android shares.
set_sources_assignment_filter([])
sources += [ "render_view_linux.cc" ]
@@ -240,7 +240,7 @@ source_set("renderer") {
"//media/mojo/interfaces",
# Defines in mojo_media_config are also pulled in here.
- "//media/mojo/services:proxy",
+ "//media/mojo/clients",
]
}
@@ -251,6 +251,10 @@ source_set("renderer") {
if (use_ozone) {
deps += [ "//ui/ozone" ]
}
+
+ if (enable_ipc_fuzzer) {
+ configs += [ "//tools/ipc_fuzzer:ipc_fuzzer_config" ]
+ }
}
# See comment at the top of //content/BUILD.gn for how this works.
diff --git a/chromium/content/renderer/DEPS b/chromium/content/renderer/DEPS
index 4a800d455d1..3ea84f5c94a 100644
--- a/chromium/content/renderer/DEPS
+++ b/chromium/content/renderer/DEPS
@@ -1,6 +1,7 @@
include_rules = [
- # Allow inclusion of specific components that we depend on. We may only
- # depend on components which we share with the mojo html_viewer.
+ # Allow inclusion of specific components that we depend on.
+ # See comment in content/DEPS for which components are allowed.
+ "+components/mus/common",
"+components/mus/public",
"+components/scheduler",
"+components/url_formatter",
diff --git a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
index ff82c5669af..02e85a92856 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -405,6 +405,19 @@ ui::AXEvent AXEventFromBlink(blink::WebAXEvent event) {
}
}
+ui::AXMarkerType AXMarkerTypeFromBlink(blink::WebAXMarkerType marker_type) {
+ switch (marker_type) {
+ case blink::WebAXMarkerTypeSpelling:
+ return ui::AX_MARKER_TYPE_SPELLING;
+ case blink::WebAXMarkerTypeGrammar:
+ return ui::AX_MARKER_TYPE_GRAMMAR;
+ case blink::WebAXMarkerTypeTextMatch:
+ return ui::AX_MARKER_TYPE_TEXT_MATCH;
+ }
+ NOTREACHED();
+ return ui::AX_MARKER_TYPE_NONE;
+}
+
ui::AXTextDirection AXTextDirectionFromBlink(
blink::WebAXTextDirection text_direction) {
switch (text_direction) {
@@ -416,10 +429,8 @@ ui::AXTextDirection AXTextDirectionFromBlink(
return ui::AX_TEXT_DIRECTION_TTB;
case blink::WebAXTextDirectionBT:
return ui::AX_TEXT_DIRECTION_BTT;
- default:
- NOTREACHED();
}
-
+ NOTREACHED();
return ui::AX_TEXT_DIRECTION_NONE;
}
@@ -477,7 +488,6 @@ ui::AXInvalidState AXInvalidStateFromBlink(
case blink::WebAXInvalidStateOther:
return ui::AX_INVALID_STATE_OTHER;
}
-
NOTREACHED();
return ui::AX_INVALID_STATE_NONE;
}
@@ -495,10 +505,8 @@ ui::AXSortDirection AXSortDirectionFromBlink(
return ui::AX_SORT_DIRECTION_DESCENDING;
case blink::WebAXSortDirectionOther:
return ui::AX_SORT_DIRECTION_OTHER;
- default:
- NOTREACHED();
}
-
+ NOTREACHED();
return ui::AX_SORT_DIRECTION_NONE;
}
@@ -520,11 +528,9 @@ ui::AXNameFrom AXNameFromFromBlink(blink::WebAXNameFrom name_from) {
return ui::AX_NAME_FROM_VALUE;
case blink::WebAXNameFromTitle:
return ui::AX_NAME_FROM_ATTRIBUTE;
- default:
- NOTREACHED();
}
-
- return ui::AX_NAME_FROM_UNINITIALIZED;
+ NOTREACHED();
+ return ui::AX_NAME_FROM_NONE;
}
ui::AXDescriptionFrom AXDescriptionFromFromBlink(
@@ -540,11 +546,9 @@ ui::AXDescriptionFrom AXDescriptionFromFromBlink(
return ui::AX_DESCRIPTION_FROM_PLACEHOLDER;
case blink::WebAXDescriptionFromRelatedElement:
return ui::AX_DESCRIPTION_FROM_RELATED_ELEMENT;
- default:
- NOTREACHED();
}
-
- return ui::AX_DESCRIPTION_FROM_UNINITIALIZED;
+ NOTREACHED();
+ return ui::AX_DESCRIPTION_FROM_NONE;
}
} // namespace content.
diff --git a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
index 4342971ba74..a2e932cd337 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
@@ -24,6 +24,8 @@ ui::AXEvent AXEventFromBlink(blink::WebAXEvent event);
// in AXNodeData instead.)
uint32_t AXStateFromBlink(const blink::WebAXObject& o);
+ui::AXMarkerType AXMarkerTypeFromBlink(blink::WebAXMarkerType marker_type);
+
ui::AXTextDirection AXTextDirectionFromBlink(
blink::WebAXTextDirection text_direction);
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
index cd6d2f87338..79f5324c143 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -13,7 +13,7 @@
#include "base/strings/utf_string_conversions.h"
#include "content/common/accessibility_messages.h"
#include "content/renderer/accessibility/blink_ax_enum_conversion.h"
-#include "content/renderer/accessibility/renderer_accessibility.h"
+#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_frame_proxy.h"
@@ -133,22 +133,20 @@ bool BlinkAXTreeSource::IsInTree(blink::WebAXObject node) const {
return false;
}
-AXContentTreeData BlinkAXTreeSource::GetTreeData() const {
- AXContentTreeData tree_data;
-
+bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const {
blink::WebDocument document = BlinkAXTreeSource::GetMainDocument();
const blink::WebAXObject& root = GetRoot();
- tree_data.doctype = "html";
- tree_data.loaded = root.isLoaded();
- tree_data.loading_progress = root.estimatedLoadingProgress();
- tree_data.mimetype = document.isXHTMLDocument() ? "text/xhtml" : "text/html";
- tree_data.title = document.title().utf8();
- tree_data.url = document.url().string().utf8();
+ tree_data->doctype = "html";
+ tree_data->loaded = root.isLoaded();
+ tree_data->loading_progress = root.estimatedLoadingProgress();
+ tree_data->mimetype = document.isXHTMLDocument() ? "text/xhtml" : "text/html";
+ tree_data->title = document.title().utf8();
+ tree_data->url = document.url().string().utf8();
WebAXObject focus = document.focusedAccessibilityObject();
if (!focus.isNull())
- tree_data.focus_id = focus.axID();
+ tree_data->focus_id = focus.axID();
WebAXObject anchor_object, focus_object;
int anchor_offset, focus_offset;
@@ -157,27 +155,27 @@ AXContentTreeData BlinkAXTreeSource::GetTreeData() const {
anchor_offset >= 0 && focus_offset >= 0) {
int32_t anchor_id = anchor_object.axID();
int32_t focus_id = focus_object.axID();
- tree_data.sel_anchor_object_id = anchor_id;
- tree_data.sel_anchor_offset = anchor_offset;
- tree_data.sel_focus_object_id = focus_id;
- tree_data.sel_focus_offset = focus_offset;
+ tree_data->sel_anchor_object_id = anchor_id;
+ tree_data->sel_anchor_offset = anchor_offset;
+ tree_data->sel_focus_object_id = focus_id;
+ tree_data->sel_focus_offset = focus_offset;
}
// Get the tree ID for this frame and the parent frame.
WebLocalFrame* web_frame = document.frame();
if (web_frame) {
RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame);
- tree_data.routing_id = render_frame->GetRoutingID();
+ tree_data->routing_id = render_frame->GetRoutingID();
// Get the tree ID for the parent frame.
blink::WebFrame* parent_web_frame = web_frame->parent();
if (parent_web_frame) {
- tree_data.parent_routing_id =
+ tree_data->parent_routing_id =
GetRoutingIdForFrameOrProxy(parent_web_frame);
}
}
- return tree_data;
+ return true;
}
blink::WebAXObject BlinkAXTreeSource::GetRoot() const {
@@ -445,6 +443,32 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
if (src.canvasHasFallbackContent())
dst->AddBoolAttribute(ui::AX_ATTR_CANVAS_HAS_FALLBACK, true);
+ // Spelling, grammar and other document markers.
+ WebVector<blink::WebAXMarkerType> src_marker_types;
+ WebVector<int> src_marker_starts;
+ WebVector<int> src_marker_ends;
+ src.markers(src_marker_types, src_marker_starts, src_marker_ends);
+ DCHECK_EQ(src_marker_types.size(), src_marker_starts.size());
+ DCHECK_EQ(src_marker_starts.size(), src_marker_ends.size());
+
+ if (src_marker_types.size()) {
+ std::vector<int32_t> marker_types;
+ std::vector<int32_t> marker_starts;
+ std::vector<int32_t> marker_ends;
+ marker_types.reserve(src_marker_types.size());
+ marker_starts.reserve(src_marker_starts.size());
+ marker_ends.reserve(src_marker_ends.size());
+ for (size_t i = 0; i < src_marker_types.size(); ++i) {
+ marker_types.push_back(
+ static_cast<int32_t>(AXMarkerTypeFromBlink(src_marker_types[i])));
+ marker_starts.push_back(src_marker_starts[i]);
+ marker_ends.push_back(src_marker_ends[i]);
+ }
+ dst->AddIntListAttribute(ui::AX_ATTR_MARKER_TYPES, marker_types);
+ dst->AddIntListAttribute(ui::AX_ATTR_MARKER_STARTS, marker_starts);
+ dst->AddIntListAttribute(ui::AX_ATTR_MARKER_ENDS, marker_ends);
+ }
+
WebNode node = src.node();
bool is_iframe = false;
@@ -471,7 +495,7 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
WebVector<int> src_line_breaks;
src.lineBreaks(src_line_breaks);
- if (src_line_breaks.size() > 0) {
+ if (src_line_breaks.size()) {
std::vector<int32_t> line_breaks;
line_breaks.reserve(src_line_breaks.size());
for (size_t i = 0; i < src_line_breaks.size(); ++i)
@@ -525,6 +549,12 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
dst->AddStringAttribute(
ui::AX_ATTR_LIVE_RELEVANT,
src.liveRegionRelevant().utf8());
+ // If we are not at the root of an atomic live region.
+ if (src.containerLiveRegionAtomic() && !src.liveRegionRoot().isDetached() &&
+ !src.liveRegionAtomic()) {
+ dst->AddIntAttribute(ui::AX_ATTR_MEMBER_OF_ID,
+ src.liveRegionRoot().axID());
+ }
dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_ATOMIC,
src.containerLiveRegionAtomic());
dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY,
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.h b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
index e7a7d4aa90f..90f7f152224 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.h
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
@@ -39,7 +39,7 @@ class BlinkAXTreeSource
void set_accessibility_focus_id(int id) { accessibility_focus_id_ = id; }
// AXTreeSource implementation.
- AXContentTreeData GetTreeData() const override;
+ bool GetTreeData(AXContentTreeData* tree_data) const override;
blink::WebAXObject GetRoot() const override;
blink::WebAXObject GetFromId(int32_t id) const override;
int32_t GetId(blink::WebAXObject node) const override;
diff --git a/chromium/content/renderer/accessibility/renderer_accessibility.cc b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
index 9b630650233..5611c7f3182 100644
--- a/chromium/content/renderer/accessibility/renderer_accessibility.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/accessibility/renderer_accessibility.h"
+#include "content/renderer/accessibility/render_accessibility_impl.h"
#include <stddef.h>
#include <stdint.h>
@@ -25,9 +25,11 @@
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebSettings.h"
#include "third_party/WebKit/public/web/WebView.h"
+#include "ui/accessibility/ax_node.h"
using blink::WebAXObject;
using blink::WebDocument;
+using blink::WebElement;
using blink::WebLocalFrame;
using blink::WebNode;
using blink::WebPoint;
@@ -44,7 +46,7 @@ namespace content {
const size_t kMaxSnapshotNodeCount = 5000;
// static
-void RendererAccessibility::SnapshotAccessibilityTree(
+void RenderAccessibilityImpl::SnapshotAccessibilityTree(
RenderFrameImpl* render_frame,
AXContentTreeUpdate* response) {
DCHECK(render_frame);
@@ -61,11 +63,12 @@ void RendererAccessibility::SnapshotAccessibilityTree(
serializer.SerializeChanges(context.root(), response);
}
-RendererAccessibility::RendererAccessibility(RenderFrameImpl* render_frame)
+RenderAccessibilityImpl::RenderAccessibilityImpl(RenderFrameImpl* render_frame)
: RenderFrameObserver(render_frame),
render_frame_(render_frame),
tree_source_(render_frame),
serializer_(&tree_source_),
+ pdf_tree_source_(nullptr),
last_scroll_offset_(gfx::Size()),
ack_pending_(false),
reset_token_(0),
@@ -102,12 +105,12 @@ RendererAccessibility::RendererAccessibility(RenderFrameImpl* render_frame)
}
}
-RendererAccessibility::~RendererAccessibility() {
+RenderAccessibilityImpl::~RenderAccessibilityImpl() {
}
-bool RendererAccessibility::OnMessageReceived(const IPC::Message& message) {
+bool RenderAccessibilityImpl::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RendererAccessibility, message)
+ IPC_BEGIN_MESSAGE_MAP(RenderAccessibilityImpl, message)
IPC_MESSAGE_HANDLER(AccessibilityMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(AccessibilityMsg_DoDefaultAction, OnDoDefaultAction)
IPC_MESSAGE_HANDLER(AccessibilityMsg_Events_ACK, OnEventsAck)
@@ -128,12 +131,12 @@ bool RendererAccessibility::OnMessageReceived(const IPC::Message& message) {
return handled;
}
-void RendererAccessibility::HandleWebAccessibilityEvent(
+void RenderAccessibilityImpl::HandleWebAccessibilityEvent(
const blink::WebAXObject& obj, blink::WebAXEvent event) {
HandleAXEvent(obj, AXEventFromBlink(event));
}
-void RendererAccessibility::HandleAccessibilityFindInPageResult(
+void RenderAccessibilityImpl::HandleAccessibilityFindInPageResult(
int identifier,
int match_index,
const blink::WebAXObject& start_object,
@@ -150,7 +153,7 @@ void RendererAccessibility::HandleAccessibilityFindInPageResult(
Send(new AccessibilityHostMsg_FindInPageResult(routing_id(), params));
}
-void RendererAccessibility::AccessibilityFocusedNodeChanged(
+void RenderAccessibilityImpl::AccessibilityFocusedNodeChanged(
const WebNode& node) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
@@ -163,7 +166,7 @@ void RendererAccessibility::AccessibilityFocusedNodeChanged(
}
}
-void RendererAccessibility::DisableAccessibility() {
+void RenderAccessibilityImpl::DisableAccessibility() {
RenderView* render_view = render_frame_->GetRenderView();
if (!render_view)
return;
@@ -179,7 +182,7 @@ void RendererAccessibility::DisableAccessibility() {
settings->setAccessibilityEnabled(false);
}
-void RendererAccessibility::HandleAXEvent(
+void RenderAccessibilityImpl::HandleAXEvent(
const blink::WebAXObject& obj, ui::AXEvent event) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
@@ -226,18 +229,55 @@ void RendererAccessibility::HandleAXEvent(
// up additional events.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&RendererAccessibility::SendPendingAccessibilityEvents,
+ base::Bind(&RenderAccessibilityImpl::SendPendingAccessibilityEvents,
weak_factory_.GetWeakPtr()));
}
}
-WebDocument RendererAccessibility::GetMainDocument() {
+int RenderAccessibilityImpl::GenerateAXID() {
+ WebAXObject root = tree_source_.GetRoot();
+ return root.generateAXID();
+}
+
+void RenderAccessibilityImpl::SetPdfTreeSource(
+ RenderAccessibilityImpl::PdfAXTreeSource* pdf_tree_source) {
+ pdf_tree_source_ = pdf_tree_source;
+ pdf_serializer_.reset(new PdfAXTreeSerializer(pdf_tree_source_));
+
+ WebAXObject root = tree_source_.GetRoot();
+ if (!root.updateLayoutAndCheckValidity())
+ return;
+
+ std::queue<WebAXObject> objs_to_explore;
+ objs_to_explore.push(root);
+ while (objs_to_explore.size()) {
+ WebAXObject obj = objs_to_explore.front();
+ objs_to_explore.pop();
+
+ WebNode node = obj.node();
+ if (!node.isNull() && node.isElementNode()) {
+ WebElement element = node.to<WebElement>();
+ if (element.hasHTMLTagName("embed")) {
+ HandleAXEvent(obj, ui::AX_EVENT_CHILDREN_CHANGED);
+ break;
+ }
+ }
+
+ // Explore children of this object.
+ std::vector<blink::WebAXObject> children;
+ tree_source_.GetChildren(obj, &children);
+ for (size_t i = 0; i < children.size(); ++i)
+ objs_to_explore.push(children[i]);
+ }
+}
+
+WebDocument RenderAccessibilityImpl::GetMainDocument() {
if (render_frame_ && render_frame_->GetWebFrame())
return render_frame_->GetWebFrame()->document();
return WebDocument();
}
-void RendererAccessibility::SendPendingAccessibilityEvents() {
+void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -289,6 +329,9 @@ void RendererAccessibility::SendPendingAccessibilityEvents() {
continue;
}
+ if (pdf_tree_source_)
+ AddPdfTreeToUpdate(&event_msg.update);
+
event_msgs.push_back(event_msg);
// For each node in the update, set the location in our map from
@@ -310,7 +353,7 @@ void RendererAccessibility::SendPendingAccessibilityEvents() {
SendLocationChanges();
}
-void RendererAccessibility::SendLocationChanges() {
+void RenderAccessibilityImpl::SendLocationChanges() {
std::vector<AccessibilityHostMsg_LocationChangeParams> messages;
// Update layout on the root of the tree.
@@ -356,7 +399,7 @@ void RendererAccessibility::SendLocationChanges() {
Send(new AccessibilityHostMsg_LocationChanges(routing_id(), messages));
}
-void RendererAccessibility::OnDoDefaultAction(int acc_obj_id) {
+void RenderAccessibilityImpl::OnDoDefaultAction(int acc_obj_id) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -372,17 +415,17 @@ void RendererAccessibility::OnDoDefaultAction(int acc_obj_id) {
obj.performDefaultAction();
}
-void RendererAccessibility::OnEventsAck() {
+void RenderAccessibilityImpl::OnEventsAck() {
DCHECK(ack_pending_);
ack_pending_ = false;
SendPendingAccessibilityEvents();
}
-void RendererAccessibility::OnFatalError() {
+void RenderAccessibilityImpl::OnFatalError() {
CHECK(false) << "Invalid accessibility tree.";
}
-void RendererAccessibility::OnHitTest(gfx::Point point) {
+void RenderAccessibilityImpl::OnHitTest(gfx::Point point) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -411,7 +454,7 @@ void RendererAccessibility::OnHitTest(gfx::Point point) {
HandleAXEvent(obj, ui::AX_EVENT_HOVER);
}
-void RendererAccessibility::OnSetAccessibilityFocus(int acc_obj_id) {
+void RenderAccessibilityImpl::OnSetAccessibilityFocus(int acc_obj_id) {
if (tree_source_.accessibility_focus_id() == acc_obj_id)
return;
@@ -431,7 +474,7 @@ void RendererAccessibility::OnSetAccessibilityFocus(int acc_obj_id) {
HandleAXEvent(obj, ui::AX_EVENT_TREE_CHANGED);
}
-void RendererAccessibility::OnReset(int reset_token) {
+void RenderAccessibilityImpl::OnReset(int reset_token) {
reset_token_ = reset_token;
serializer_.Reset();
pending_events_.clear();
@@ -446,7 +489,7 @@ void RendererAccessibility::OnReset(int reset_token) {
}
}
-void RendererAccessibility::OnScrollToMakeVisible(
+void RenderAccessibilityImpl::OnScrollToMakeVisible(
int acc_obj_id, gfx::Rect subfocus) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
@@ -470,7 +513,8 @@ void RendererAccessibility::OnScrollToMakeVisible(
HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_LAYOUT_COMPLETE);
}
-void RendererAccessibility::OnScrollToPoint(int acc_obj_id, gfx::Point point) {
+void RenderAccessibilityImpl::OnScrollToPoint(
+ int acc_obj_id, gfx::Point point) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -492,7 +536,7 @@ void RendererAccessibility::OnScrollToPoint(int acc_obj_id, gfx::Point point) {
HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_LAYOUT_COMPLETE);
}
-void RendererAccessibility::OnSetScrollOffset(int acc_obj_id,
+void RenderAccessibilityImpl::OnSetScrollOffset(int acc_obj_id,
gfx::Point offset) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
@@ -505,7 +549,7 @@ void RendererAccessibility::OnSetScrollOffset(int acc_obj_id,
obj.setScrollOffset(WebPoint(offset.x(), offset.y()));
}
-void RendererAccessibility::OnSetFocus(int acc_obj_id) {
+void RenderAccessibilityImpl::OnSetFocus(int acc_obj_id) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -535,7 +579,7 @@ void RendererAccessibility::OnSetFocus(int acc_obj_id) {
obj.setFocused(true);
}
-void RendererAccessibility::OnSetSelection(int anchor_acc_obj_id,
+void RenderAccessibilityImpl::OnSetSelection(int anchor_acc_obj_id,
int anchor_offset,
int focus_acc_obj_id,
int focus_offset) {
@@ -573,7 +617,7 @@ void RendererAccessibility::OnSetSelection(int anchor_acc_obj_id,
HandleAXEvent(root, ui::AX_EVENT_LAYOUT_COMPLETE);
}
-void RendererAccessibility::OnSetValue(
+void RenderAccessibilityImpl::OnSetValue(
int acc_obj_id,
base::string16 value) {
const WebDocument& document = GetMainDocument();
@@ -592,7 +636,7 @@ void RendererAccessibility::OnSetValue(
HandleAXEvent(obj, ui::AX_EVENT_VALUE_CHANGED);
}
-void RendererAccessibility::OnShowContextMenu(int acc_obj_id) {
+void RenderAccessibilityImpl::OnShowContextMenu(int acc_obj_id) {
const WebDocument& document = GetMainDocument();
if (document.isNull())
return;
@@ -608,4 +652,30 @@ void RendererAccessibility::OnShowContextMenu(int acc_obj_id) {
obj.showContextMenu();
}
+void RenderAccessibilityImpl::OnDestruct() {
+ delete this;
+}
+
+void RenderAccessibilityImpl::AddPdfTreeToUpdate(AXContentTreeUpdate* update) {
+ for (size_t i = 0; i < update->nodes.size(); ++i) {
+ if (update->nodes[i].role == ui::AX_ROLE_EMBEDDED_OBJECT) {
+ const ui::AXNode* root = pdf_tree_source_->GetRoot();
+ update->nodes[i].child_ids.push_back(root->id());
+
+ ui::AXTreeUpdate pdf_update;
+ pdf_serializer_->SerializeChanges(root, &pdf_update);
+
+ // We have to copy the updated nodes using a loop because we're
+ // converting from a generic ui::AXNodeData to a vector of its
+ // content-specific subclass AXContentNodeData.
+ size_t old_count = update->nodes.size();
+ size_t new_count = pdf_update.nodes.size();
+ update->nodes.resize(old_count + new_count);
+ for (size_t i = 0; i < new_count; ++i)
+ update->nodes[old_count + i] = pdf_update.nodes[i];
+ break;
+ }
+ }
+}
+
} // namespace content
diff --git a/chromium/content/renderer/accessibility/renderer_accessibility.h b/chromium/content/renderer/accessibility/render_accessibility_impl.h
index 91bcd553afc..f56d2add2cf 100644
--- a/chromium/content/renderer/accessibility/renderer_accessibility.h
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_H_
-#define CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_H_
+#ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDER_ACCESSIBILITY_IMPL_H_
+#define CONTENT_RENDERER_ACCESSIBILITY_RENDER_ACCESSIBILITY_IMPL_H_
#include <vector>
@@ -11,9 +11,11 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/ax_content_node_data.h"
+#include "content/public/renderer/render_accessibility.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/accessibility/blink_ax_tree_source.h"
#include "third_party/WebKit/public/web/WebAXObject.h"
+#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_serializer.h"
struct AccessibilityHostMsg_EventParams;
@@ -47,7 +49,9 @@ class RenderFrameImpl;
// representation of that tree whenever it changes. It also handles requests
// from the browser to perform accessibility actions on nodes in the tree
// (e.g., change focus, or click on a button).
-class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
+class CONTENT_EXPORT RenderAccessibilityImpl
+ : public RenderAccessibility,
+ RenderFrameObserver {
public:
// Request a one-time snapshot of the accessibility tree without
// enabling accessibility if it wasn't already enabled.
@@ -55,8 +59,12 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
RenderFrameImpl* render_frame,
AXContentTreeUpdate* response);
- explicit RendererAccessibility(RenderFrameImpl* render_frame);
- ~RendererAccessibility() override;
+ explicit RenderAccessibilityImpl(RenderFrameImpl* render_frame);
+ ~RenderAccessibilityImpl() override;
+
+ // RenderAccessibility implementation.
+ int GenerateAXID() override;
+ void SetPdfTreeSource(PdfAXTreeSource* source) override;
// RenderFrameObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
@@ -76,7 +84,7 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
void AccessibilityFocusedNodeChanged(const blink::WebNode& node);
- // This can be called before deleting a RendererAccessibility instance due
+ // This can be called before deleting a RenderAccessibilityImpl instance due
// to the accessibility mode changing, as opposed to during frame destruction
// (when there'd be no point).
void DisableAccessibility();
@@ -100,6 +108,9 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
RenderFrameImpl* render_frame_;
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Handlers for messages from the browser to the renderer.
void OnDoDefaultAction(int acc_obj_id);
void OnEventsAck();
@@ -118,6 +129,8 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
void OnSetValue(int acc_obj_id, base::string16 value);
void OnShowContextMenu(int acc_obj_id);
+ void AddPdfTreeToUpdate(AXContentTreeUpdate* update);
+
// Events from Blink are collected until they are ready to be
// sent to the browser.
std::vector<AccessibilityHostMsg_EventParams> pending_events_;
@@ -132,6 +145,12 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
AXContentTreeData>;
BlinkAXTreeSerializer serializer_;
+ using PdfAXTreeSerializer = ui::AXTreeSerializer<const ui::AXNode*,
+ ui::AXNodeData,
+ ui::AXTreeData>;
+ std::unique_ptr<PdfAXTreeSerializer> pdf_serializer_;
+ PdfAXTreeSource* pdf_tree_source_;
+
// Current location of every object, so we can detect when it moves.
base::hash_map<int, gfx::Rect> locations_;
@@ -148,9 +167,9 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
int reset_token_;
// So we can queue up tasks to be executed later.
- base::WeakPtrFactory<RendererAccessibility> weak_factory_;
+ base::WeakPtrFactory<RenderAccessibilityImpl> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(RendererAccessibility);
+ DISALLOW_COPY_AND_ASSIGN(RenderAccessibilityImpl);
};
} // namespace content
diff --git a/chromium/content/renderer/accessibility/renderer_accessibility_browsertest.cc b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
index 19566520c3d..77c180742c6 100644
--- a/chromium/content/renderer/accessibility/renderer_accessibility_browsertest.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
@@ -12,7 +14,7 @@
#include "content/common/view_message_enums.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/render_view_test.h"
-#include "content/renderer/accessibility/renderer_accessibility.h"
+#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,20 +29,20 @@ using blink::WebDocument;
namespace content {
-class TestRendererAccessibility : public RendererAccessibility {
+class TestRenderAccessibilityImpl : public RenderAccessibilityImpl {
public:
- explicit TestRendererAccessibility(RenderFrameImpl* render_frame)
- : RendererAccessibility(render_frame) {
+ explicit TestRenderAccessibilityImpl(RenderFrameImpl* render_frame)
+ : RenderAccessibilityImpl(render_frame) {
}
void SendPendingAccessibilityEvents() {
- RendererAccessibility::SendPendingAccessibilityEvents();
+ RenderAccessibilityImpl::SendPendingAccessibilityEvents();
}
};
-class RendererAccessibilityTest : public RenderViewTest {
+class RenderAccessibilityImplTest : public RenderViewTest {
public:
- RendererAccessibilityTest() {}
+ RenderAccessibilityImplTest() {}
RenderViewImpl* view() {
return static_cast<RenderViewImpl*>(view_);
@@ -73,9 +75,9 @@ class RendererAccessibilityTest : public RenderViewTest {
const IPC::Message* message =
sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID);
ASSERT_TRUE(message);
- base::Tuple<std::vector<AccessibilityHostMsg_EventParams>, int> param;
+ std::tuple<std::vector<AccessibilityHostMsg_EventParams>, int> param;
AccessibilityHostMsg_Events::Read(message, &param);
- *param_list = base::get<0>(param);
+ *param_list = std::get<0>(param);
}
void GetLastAccEvent(
@@ -95,12 +97,12 @@ class RendererAccessibilityTest : public RenderViewTest {
protected:
IPC::TestSink* sink_;
- DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityTest);
+ DISALLOW_COPY_AND_ASSIGN(RenderAccessibilityImplTest);
};
-TEST_F(RendererAccessibilityTest, SendFullAccessibilityTreeOnReload) {
- // The job of RendererAccessibility is to serialize the
+TEST_F(RenderAccessibilityImplTest, SendFullAccessibilityTreeOnReload) {
+ // The job of RenderAccessibilityImpl is to serialize the
// accessibility tree built by WebKit and send it to the browser.
// When the accessibility tree changes, it tries to send only
// the nodes that actually changed or were reparented. This test
@@ -115,9 +117,9 @@ TEST_F(RendererAccessibilityTest, SendFullAccessibilityTreeOnReload) {
"</body>";
LoadHTML(html.c_str());
- // Creating a RendererAccessibility should sent the tree to the browser.
- std::unique_ptr<TestRendererAccessibility> accessibility(
- new TestRendererAccessibility(frame()));
+ // Creating a RenderAccessibilityImpl should sent the tree to the browser.
+ std::unique_ptr<TestRenderAccessibilityImpl> accessibility(
+ new TestRenderAccessibilityImpl(frame()));
accessibility->SendPendingAccessibilityEvents();
EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser());
@@ -166,8 +168,8 @@ TEST_F(RendererAccessibilityTest, SendFullAccessibilityTreeOnReload) {
EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser());
}
-TEST_F(RendererAccessibilityTest, HideAccessibilityObject) {
- // Test RendererAccessibility and make sure it sends the
+TEST_F(RenderAccessibilityImplTest, HideAccessibilityObject) {
+ // Test RenderAccessibilityImpl and make sure it sends the
// proper event to the browser when an object in the tree
// is hidden, but its children are not.
std::string html =
@@ -181,8 +183,8 @@ TEST_F(RendererAccessibilityTest, HideAccessibilityObject) {
"</body>";
LoadHTML(html.c_str());
- std::unique_ptr<TestRendererAccessibility> accessibility(
- new TestRendererAccessibility(frame()));
+ std::unique_ptr<TestRenderAccessibilityImpl> accessibility(
+ new TestRenderAccessibilityImpl(frame()));
accessibility->SendPendingAccessibilityEvents();
EXPECT_EQ(4, CountAccessibilityNodesSentToBrowser());
@@ -209,7 +211,7 @@ TEST_F(RendererAccessibilityTest, HideAccessibilityObject) {
GetLastAccEvent(&event);
ASSERT_EQ(2U, event.update.nodes.size());
- // RendererAccessibility notices that 'C' is being reparented,
+ // RenderAccessibilityImpl notices that 'C' is being reparented,
// so it clears the subtree rooted at 'A', then updates 'A' and then 'C'.
EXPECT_EQ(node_a.axID(), event.update.node_id_to_clear);
EXPECT_EQ(node_a.axID(), event.update.nodes[0].id);
@@ -217,8 +219,8 @@ TEST_F(RendererAccessibilityTest, HideAccessibilityObject) {
EXPECT_EQ(2, CountAccessibilityNodesSentToBrowser());
}
-TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) {
- // Test RendererAccessibility and make sure it sends the
+TEST_F(RenderAccessibilityImplTest, ShowAccessibilityObject) {
+ // Test RenderAccessibilityImpl and make sure it sends the
// proper event to the browser when an object in the tree
// is shown, causing its own already-visible children to be
// reparented to it.
@@ -233,8 +235,8 @@ TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) {
"</body>";
LoadHTML(html.c_str());
- std::unique_ptr<TestRendererAccessibility> accessibility(
- new TestRendererAccessibility(frame()));
+ std::unique_ptr<TestRenderAccessibilityImpl> accessibility(
+ new TestRenderAccessibilityImpl(frame()));
accessibility->SendPendingAccessibilityEvents();
EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser());
@@ -266,8 +268,8 @@ TEST_F(RendererAccessibilityTest, ShowAccessibilityObject) {
EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser());
}
-TEST_F(RendererAccessibilityTest, DetachAccessibilityObject) {
- // Test RendererAccessibility and make sure it sends the
+TEST_F(RenderAccessibilityImplTest, DetachAccessibilityObject) {
+ // Test RenderAccessibilityImpl and make sure it sends the
// proper event to the browser when an object in the tree
// is detached, but its children are not. This can happen when
// a layout occurs and an anonymous render block is no longer needed.
@@ -277,8 +279,8 @@ TEST_F(RendererAccessibilityTest, DetachAccessibilityObject) {
"</body>";
LoadHTML(html.c_str());
- std::unique_ptr<TestRendererAccessibility> accessibility(
- new TestRendererAccessibility(frame()));
+ std::unique_ptr<TestRenderAccessibilityImpl> accessibility(
+ new TestRenderAccessibilityImpl(frame()));
accessibility->SendPendingAccessibilityEvents();
EXPECT_EQ(7, CountAccessibilityNodesSentToBrowser());
diff --git a/chromium/content/renderer/android/disambiguation_popup_helper.cc b/chromium/content/renderer/android/disambiguation_popup_helper.cc
index 93a561f3839..19f2c563ff8 100644
--- a/chromium/content/renderer/android/disambiguation_popup_helper.cc
+++ b/chromium/content/renderer/android/disambiguation_popup_helper.cc
@@ -6,6 +6,8 @@
#include <stddef.h>
+#include <algorithm>
+
#include "third_party/WebKit/public/platform/WebRect.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -33,23 +35,25 @@ const float kDisambiguationPopupMinScale = 2.0;
// a certain clickable size after zooming
float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects,
float total_scale) {
- using std::min;
- using std::max;
- if (!target_rects.size()) // shall never reach
+ DCHECK_GT(total_scale, 0.0f);
+ if (!target_rects.size()) {
+ NOTREACHED();
return kDisambiguationPopupMinScale;
- float smallest_target = min(target_rects[0].width * total_scale,
- target_rects[0].height * total_scale);
+ }
+ int smallest_target = std::min(target_rects[0].width, target_rects[0].height);
for (size_t i = 1; i < target_rects.size(); i++) {
- smallest_target = min(smallest_target, target_rects[i].width * total_scale);
- smallest_target = min(smallest_target,
- target_rects[i].height * total_scale);
+ smallest_target = std::min(
+ {smallest_target, target_rects[i].width, target_rects[i].height});
}
- smallest_target = max(smallest_target, 1.0f);
- return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale,
- kDisambiguationPopupMinimumTouchSize / smallest_target)) * total_scale;
+ const float smallest_target_f = std::max(smallest_target * total_scale, 1.0f);
+ return std::min(kDisambiguationPopupMaxScale,
+ std::max(kDisambiguationPopupMinScale,
+ kDisambiguationPopupMinimumTouchSize /
+ smallest_target_f)) *
+ total_scale;
}
-void TrimEdges(int *e1, int *e2, int max_combined) {
+void TrimEdges(int* e1, int* e2, int max_combined) {
if (*e1 + *e2 <= max_combined)
return;
@@ -89,6 +93,7 @@ gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect,
namespace content {
+// static
float DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
const gfx::Rect& tap_rect,
const WebVector<WebRect>& target_rects,
diff --git a/chromium/content/renderer/android/renderer_date_time_picker.cc b/chromium/content/renderer/android/renderer_date_time_picker.cc
index b936490b032..d8c0c652214 100644
--- a/chromium/content/renderer/android/renderer_date_time_picker.cc
+++ b/chromium/content/renderer/android/renderer_date_time_picker.cc
@@ -110,4 +110,8 @@ void RendererDateTimePicker::OnCancel() {
static_cast<RenderViewImpl*>(render_view())->DismissDateTimeDialog();
}
+void RendererDateTimePicker::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/android/renderer_date_time_picker.h b/chromium/content/renderer/android/renderer_date_time_picker.h
index d04016bf271..2e9741aa0db 100644
--- a/chromium/content/renderer/android/renderer_date_time_picker.h
+++ b/chromium/content/renderer/android/renderer_date_time_picker.h
@@ -34,6 +34,7 @@ class RendererDateTimePicker : public RenderViewObserver {
// RenderViewObserver
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
blink::WebDateTimeChooserParams chooser_params_;
blink::WebDateTimeChooserCompletion* chooser_completion_; // Not owned by us
diff --git a/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.cc b/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.cc
deleted file mode 100644
index 7bb1dc8f727..00000000000
--- a/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
-
-#include "cc/output/begin_frame_args.h"
-#include "content/renderer/android/synchronous_compositor_registry.h"
-
-namespace content {
-
-SynchronousCompositorExternalBeginFrameSource::
- SynchronousCompositorExternalBeginFrameSource(
- int routing_id,
- SynchronousCompositorRegistry* registry)
- : routing_id_(routing_id),
- registry_(registry),
- registered_(false),
- client_(nullptr) {
- thread_checker_.DetachFromThread();
-}
-
-SynchronousCompositorExternalBeginFrameSource::
- ~SynchronousCompositorExternalBeginFrameSource() {
- DCHECK(CalledOnValidThread());
-
- if (registered_) {
- registry_->UnregisterBeginFrameSource(routing_id_, this);
- }
- DCHECK(!client_);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::BeginFrame(
- const cc::BeginFrameArgs& args) {
- DCHECK(CalledOnValidThread());
- CallOnBeginFrame(args);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::SetClient(
- SynchronousCompositorExternalBeginFrameSourceClient* client) {
- DCHECK(CalledOnValidThread());
- if (client_ == client)
- return;
-
- if (client_)
- client_->OnNeedsBeginFramesChange(false);
-
- client_ = client;
-
- if (client_)
- client_->OnNeedsBeginFramesChange(needs_begin_frames());
-
- // State without client is paused, and default client state is not paused.
- SetBeginFrameSourcePaused(!client_);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::OnNeedsBeginFramesChanged(
- bool needs_begin_frames) {
- DCHECK(CalledOnValidThread());
- if (client_)
- client_->OnNeedsBeginFramesChange(needs_begin_frames);
-}
-
-void SynchronousCompositorExternalBeginFrameSource::AddObserver(
- cc::BeginFrameObserver* obs) {
- DCHECK(CalledOnValidThread());
- BeginFrameSourceBase::AddObserver(obs);
- if (registered_)
- return;
- registry_->RegisterBeginFrameSource(routing_id_, this);
- registered_ = true;
-}
-
-bool
-SynchronousCompositorExternalBeginFrameSource::CalledOnValidThread() const {
- return thread_checker_.CalledOnValidThread();
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.h b/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.h
deleted file mode 100644
index e058c37662e..00000000000
--- a/chromium/content/renderer/android/synchronous_compositor_external_begin_frame_source.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-#define CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "cc/scheduler/begin_frame_source.h"
-
-namespace content {
-
-class SynchronousCompositorRegistry;
-
-class SynchronousCompositorExternalBeginFrameSourceClient {
- public:
- virtual void OnNeedsBeginFramesChange(bool needs_begin_frames) = 0;
-
- protected:
- virtual ~SynchronousCompositorExternalBeginFrameSourceClient() {}
-};
-
-// Make sure that this is initialized and set to client before output
-// surface is bound to compositor.
-class SynchronousCompositorExternalBeginFrameSource
- : public cc::BeginFrameSourceBase {
- public:
- SynchronousCompositorExternalBeginFrameSource(
- int routing_id,
- SynchronousCompositorRegistry* registry);
- ~SynchronousCompositorExternalBeginFrameSource() override;
-
- void BeginFrame(const cc::BeginFrameArgs& args);
- void SetClient(SynchronousCompositorExternalBeginFrameSourceClient* client);
- using cc::BeginFrameSourceBase::SetBeginFrameSourcePaused;
-
- // cc::BeginFrameSourceBase implementation.
- void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
- void AddObserver(cc::BeginFrameObserver* obs) override;
-
- private:
- bool CalledOnValidThread() const;
-
- const int routing_id_;
- SynchronousCompositorRegistry* const registry_;
- bool registered_;
-
- // Not owned.
- SynchronousCompositorExternalBeginFrameSourceClient* client_;
-
- base::ThreadChecker thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorExternalBeginFrameSource);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
diff --git a/chromium/content/renderer/android/synchronous_compositor_filter.cc b/chromium/content/renderer/android/synchronous_compositor_filter.cc
index 43b7131a2b0..a73fde1af96 100644
--- a/chromium/content/renderer/android/synchronous_compositor_filter.cc
+++ b/chromium/content/renderer/android/synchronous_compositor_filter.cc
@@ -154,32 +154,6 @@ void SynchronousCompositorFilter::UnregisterOutputSurface(
RemoveEntryIfNeeded(routing_id);
}
-void SynchronousCompositorFilter::RegisterBeginFrameSource(
- int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- DCHECK(begin_frame_source);
- Entry& entry = entry_map_[routing_id];
- DCHECK(!entry.begin_frame_source);
- entry.begin_frame_source = begin_frame_source;
- CheckIsReady(routing_id);
-}
-
-void SynchronousCompositorFilter::UnregisterBeginFrameSource(
- int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- DCHECK(begin_frame_source);
- DCHECK(ContainsKey(entry_map_, routing_id));
- Entry& entry = entry_map_[routing_id];
- DCHECK_EQ(begin_frame_source, entry.begin_frame_source);
-
- if (entry.IsReady())
- UnregisterObjects(routing_id);
- entry.begin_frame_source = nullptr;
- RemoveEntryIfNeeded(routing_id);
-}
-
void SynchronousCompositorFilter::CheckIsReady(int routing_id) {
DCHECK(compositor_task_runner_->BelongsToCurrentThread());
DCHECK(ContainsKey(entry_map_, routing_id));
@@ -187,9 +161,8 @@ void SynchronousCompositorFilter::CheckIsReady(int routing_id) {
if (filter_ready_ && entry.IsReady()) {
DCHECK(!sync_compositor_map_.contains(routing_id));
std::unique_ptr<SynchronousCompositorProxy> proxy(
- new SynchronousCompositorProxy(
- routing_id, this, entry.begin_frame_source,
- entry.synchronous_input_handler_proxy, &input_handler_));
+ new SynchronousCompositorProxy(routing_id, this,
+ entry.synchronous_input_handler_proxy));
if (entry.output_surface)
proxy->SetOutputSurface(entry.output_surface);
sync_compositor_map_.add(routing_id, std::move(proxy));
@@ -206,53 +179,11 @@ void SynchronousCompositorFilter::RemoveEntryIfNeeded(int routing_id) {
DCHECK(compositor_task_runner_->BelongsToCurrentThread());
DCHECK(ContainsKey(entry_map_, routing_id));
Entry& entry = entry_map_[routing_id];
- if (!entry.begin_frame_source && !entry.output_surface &&
- !entry.synchronous_input_handler_proxy) {
+ if (!entry.output_surface && !entry.synchronous_input_handler_proxy) {
entry_map_.erase(routing_id);
}
}
-void SynchronousCompositorFilter::SetBoundHandler(const Handler& handler) {
- compositor_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &SynchronousCompositorFilter::SetBoundHandlerOnCompositorThread, this,
- handler));
-}
-
-void SynchronousCompositorFilter::RegisterRoutingID(int routing_id) {}
-void SynchronousCompositorFilter::UnregisterRoutingID(int routing_id) {}
-
-void SynchronousCompositorFilter::SetBoundHandlerOnCompositorThread(
- const Handler& handler) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- input_handler_ = handler;
-}
-
-void SynchronousCompositorFilter::DidOverscroll(
- int routing_id,
- const DidOverscrollParams& params) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- SynchronousCompositorProxy* proxy = FindProxy(routing_id);
- if (!proxy) {
- DLOG(WARNING) << "No matching proxy in DidOverScroll " << routing_id;
- return;
- }
- proxy->DidOverscroll(params);
-}
-
-void SynchronousCompositorFilter::DidStartFlinging(int routing_id) {}
-
-void SynchronousCompositorFilter::DidStopFlinging(int routing_id) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- Send(new InputHostMsg_DidStopFlinging(routing_id));
-}
-
-void SynchronousCompositorFilter::NotifyInputEventHandled(
- int routing_id,
- blink::WebInputEvent::Type type,
- InputEventAckState ack_result) {}
-
void SynchronousCompositorFilter::DidAddSynchronousHandlerProxy(
int routing_id,
ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
@@ -277,12 +208,12 @@ void SynchronousCompositorFilter::DidRemoveSynchronousHandlerProxy(
}
SynchronousCompositorFilter::Entry::Entry()
- : begin_frame_source(nullptr),
- output_surface(nullptr),
+ : output_surface(nullptr),
synchronous_input_handler_proxy(nullptr) {}
+// TODO(boliu): refactor this
bool SynchronousCompositorFilter::Entry::IsReady() {
- return begin_frame_source && synchronous_input_handler_proxy;
+ return synchronous_input_handler_proxy;
}
} // namespace content
diff --git a/chromium/content/renderer/android/synchronous_compositor_filter.h b/chromium/content/renderer/android/synchronous_compositor_filter.h
index b7cee7bbf42..a188fdbd7af 100644
--- a/chromium/content/renderer/android/synchronous_compositor_filter.h
+++ b/chromium/content/renderer/android/synchronous_compositor_filter.h
@@ -29,7 +29,6 @@ class SynchronousCompositorFilter
: public IPC::MessageFilter,
public IPC::Sender,
public SynchronousCompositorRegistry,
- public InputHandlerManagerClient,
public SynchronousInputHandlerProxyClient {
public:
SynchronousCompositorFilter(const scoped_refptr<base::SingleThreadTaskRunner>&
@@ -53,24 +52,6 @@ class SynchronousCompositorFilter
void UnregisterOutputSurface(
int routing_id,
SynchronousCompositorOutputSurface* output_surface) override;
- void RegisterBeginFrameSource(int routing_id,
- SynchronousCompositorExternalBeginFrameSource*
- begin_frame_source) override;
- void UnregisterBeginFrameSource(int routing_id,
- SynchronousCompositorExternalBeginFrameSource*
- begin_frame_source) override;
-
- // InputHandlerManagerClient overrides.
- void SetBoundHandler(const Handler& handler) override;
- void RegisterRoutingID(int routing_id) override;
- void UnregisterRoutingID(int routing_id) override;
- void DidOverscroll(int routing_id,
- const DidOverscrollParams& params) override;
- void DidStartFlinging(int routing_id) override;
- void DidStopFlinging(int routing_id) override;
- void NotifyInputEventHandled(int routing_id,
- blink::WebInputEvent::Type type,
- InputEventAckState ack_result) override;
// SynchronousInputHandlerProxyClient overrides.
void DidAddSynchronousHandlerProxy(
@@ -88,7 +69,6 @@ class SynchronousCompositorFilter
// Compositor thread methods.
void FilterReadyyOnCompositorThread();
void OnMessageReceivedOnCompositorThread(const IPC::Message& message);
- void SetBoundHandlerOnCompositorThread(const Handler& handler);
void CheckIsReady(int routing_id);
void UnregisterObjects(int routing_id);
void RemoveEntryIfNeeded(int routing_id);
@@ -105,11 +85,9 @@ class SynchronousCompositorFilter
base::ScopedPtrHashMap<int /* routing_id */,
std::unique_ptr<SynchronousCompositorProxy>>;
SyncCompositorMap sync_compositor_map_;
- Handler input_handler_;
bool filter_ready_;
struct Entry {
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source;
SynchronousCompositorOutputSurface* output_surface;
ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy;
diff --git a/chromium/content/renderer/android/synchronous_compositor_output_surface.cc b/chromium/content/renderer/android/synchronous_compositor_output_surface.cc
index 119dac59883..37d3a23e90f 100644
--- a/chromium/content/renderer/android/synchronous_compositor_output_surface.cc
+++ b/chromium/content/renderer/android/synchronous_compositor_output_surface.cc
@@ -7,14 +7,17 @@
#include <vector>
#include "base/auto_reset.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/context_provider.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/software_output_device.h"
#include "content/common/android/sync_compositor_messages.h"
-#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
#include "content/renderer/android/synchronous_compositor_filter.h"
#include "content/renderer/android/synchronous_compositor_registry.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
@@ -69,17 +72,15 @@ class SynchronousCompositorOutputSurface::SoftwareDevice
};
SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
- const scoped_refptr<cc::ContextProvider>& context_provider,
- const scoped_refptr<cc::ContextProvider>& worker_context_provider,
+ scoped_refptr<cc::ContextProvider> context_provider,
+ scoped_refptr<cc::ContextProvider> worker_context_provider,
int routing_id,
uint32_t output_surface_id,
SynchronousCompositorRegistry* registry,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue)
- : cc::OutputSurface(
- context_provider,
- worker_context_provider,
- nullptr,
- std::unique_ptr<cc::SoftwareOutputDevice>(new SoftwareDevice(this))),
+ : cc::OutputSurface(std::move(context_provider),
+ std::move(worker_context_provider),
+ base::MakeUnique<SoftwareDevice>(this)),
routing_id_(routing_id),
output_surface_id_(output_surface_id),
registry_(registry),
@@ -107,6 +108,8 @@ void SynchronousCompositorOutputSurface::SetSyncClient(
SynchronousCompositorOutputSurfaceClient* compositor) {
DCHECK(CalledOnValidThread());
sync_client_ = compositor;
+ if (sync_client_)
+ Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_));
}
bool SynchronousCompositorOutputSurface::OnMessageReceived(
@@ -132,7 +135,6 @@ bool SynchronousCompositorOutputSurface::BindToClient(
base::Unretained(this)));
registry_->RegisterOutputSurface(routing_id_, this);
registered_ = true;
- Send(new SyncCompositorHostMsg_OutputSurfaceCreated(routing_id_));
return true;
}
@@ -146,18 +148,20 @@ void SynchronousCompositorOutputSurface::DetachFromClient() {
CancelFallbackTick();
}
-void SynchronousCompositorOutputSurface::Reshape(const gfx::Size& size,
- float scale_factor,
- bool has_alpha) {
+void SynchronousCompositorOutputSurface::Reshape(
+ const gfx::Size& size,
+ float scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha) {
// Intentional no-op: surface size is controlled by the embedder.
}
void SynchronousCompositorOutputSurface::SwapBuffers(
- cc::CompositorFrame* frame) {
+ cc::CompositorFrame frame) {
DCHECK(CalledOnValidThread());
DCHECK(sync_client_);
if (!fallback_tick_running_) {
- sync_client_->SwapBuffers(output_surface_id_, frame);
+ sync_client_->SwapBuffers(output_surface_id_, std::move(frame));
DeliverMessages();
}
client_->DidSwapBuffers();
@@ -191,13 +195,24 @@ void SynchronousCompositorOutputSurface::Invalidate() {
fallback_tick_.Reset(
base::Bind(&SynchronousCompositorOutputSurface::FallbackTickFired,
base::Unretained(this)));
- base::MessageLoop::current()->PostDelayedTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, fallback_tick_.callback(),
base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
fallback_tick_pending_ = true;
}
}
+void SynchronousCompositorOutputSurface::BindFramebuffer() {
+ // This is a delegating output surface, no framebuffer/direct drawing support.
+ NOTREACHED();
+}
+
+uint32_t SynchronousCompositorOutputSurface::GetFramebufferCopyTextureFormat() {
+ // This is a delegating output surface, no framebuffer/direct drawing support.
+ NOTREACHED();
+ return 0;
+}
+
void SynchronousCompositorOutputSurface::DemandDrawHw(
const gfx::Size& surface_size,
const gfx::Transform& transform,
diff --git a/chromium/content/renderer/android/synchronous_compositor_output_surface.h b/chromium/content/renderer/android/synchronous_compositor_output_surface.h
index 672cf2d234c..09720941418 100644
--- a/chromium/content/renderer/android/synchronous_compositor_output_surface.h
+++ b/chromium/content/renderer/android/synchronous_compositor_output_surface.h
@@ -42,7 +42,7 @@ class SynchronousCompositorOutputSurfaceClient {
virtual void DidActivatePendingTree() = 0;
virtual void Invalidate() = 0;
virtual void SwapBuffers(uint32_t output_surface_id,
- cc::CompositorFrame* frame) = 0;
+ cc::CompositorFrame frame) = 0;
protected:
virtual ~SynchronousCompositorOutputSurfaceClient() {}
@@ -60,8 +60,8 @@ class SynchronousCompositorOutputSurface
: NON_EXPORTED_BASE(public cc::OutputSurface) {
public:
SynchronousCompositorOutputSurface(
- const scoped_refptr<cc::ContextProvider>& context_provider,
- const scoped_refptr<cc::ContextProvider>& worker_context_provider,
+ scoped_refptr<cc::ContextProvider> context_provider,
+ scoped_refptr<cc::ContextProvider> worker_context_provider,
int routing_id,
uint32_t output_surface_id,
SynchronousCompositorRegistry* registry,
@@ -76,9 +76,12 @@ class SynchronousCompositorOutputSurface
void DetachFromClient() override;
void Reshape(const gfx::Size& size,
float scale_factor,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
- void SwapBuffers(cc::CompositorFrame* frame) override;
+ void SwapBuffers(cc::CompositorFrame frame) override;
void Invalidate() override;
+ void BindFramebuffer() override;
+ uint32_t GetFramebufferCopyTextureFormat() override;
// Partial SynchronousCompositor API implementation.
void DemandDrawHw(const gfx::Size& surface_size,
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy.cc b/chromium/content/renderer/android/synchronous_compositor_proxy.cc
index ae6a13135e0..6b9883b5a21 100644
--- a/chromium/content/renderer/android/synchronous_compositor_proxy.cc
+++ b/chromium/content/renderer/android/synchronous_compositor_proxy.cc
@@ -17,7 +17,6 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/events/latency_info.h"
#include "ui/gfx/skia_util.h"
namespace content {
@@ -25,14 +24,10 @@ namespace content {
SynchronousCompositorProxy::SynchronousCompositorProxy(
int routing_id,
IPC::Sender* sender,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- ui::SynchronousInputHandlerProxy* input_handler_proxy,
- InputHandlerManagerClient::Handler* handler)
+ ui::SynchronousInputHandlerProxy* input_handler_proxy)
: routing_id_(routing_id),
sender_(sender),
- begin_frame_source_(begin_frame_source),
input_handler_proxy_(input_handler_proxy),
- input_handler_(handler),
use_in_process_zero_copy_software_draw_(
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess)),
@@ -46,18 +41,15 @@ SynchronousCompositorProxy::SynchronousCompositorProxy(
max_page_scale_factor_(0.f),
need_animate_scroll_(false),
need_invalidate_count_(0u),
- need_begin_frame_(false),
did_activate_pending_tree_count_(0u) {
- DCHECK(begin_frame_source_);
DCHECK(input_handler_proxy_);
- DCHECK(input_handler_);
- begin_frame_source_->SetClient(this);
input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this);
}
SynchronousCompositorProxy::~SynchronousCompositorProxy() {
- SetOutputSurface(nullptr);
- begin_frame_source_->SetClient(nullptr);
+ // The OutputSurface is destroyed/removed by the compositor before shutting
+ // down everything.
+ DCHECK_EQ(output_surface_, nullptr);
input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(nullptr);
}
@@ -102,14 +94,6 @@ void SynchronousCompositorProxy::UpdateRootLayerState(
}
}
-void SynchronousCompositorProxy::OnNeedsBeginFramesChange(
- bool needs_begin_frames) {
- if (need_begin_frame_ == needs_begin_frames)
- return;
- need_begin_frame_ = needs_begin_frames;
- SendAsyncRendererStateIfNeeded();
-}
-
void SynchronousCompositorProxy::Invalidate() {
++need_invalidate_count_;
SendAsyncRendererStateIfNeeded();
@@ -139,7 +123,6 @@ void SynchronousCompositorProxy::PopulateCommonParams(
params->max_page_scale_factor = max_page_scale_factor_;
params->need_animate_scroll = need_animate_scroll_;
params->need_invalidate_count = need_invalidate_count_;
- params->need_begin_frame = need_begin_frame_;
params->did_activate_pending_tree_count = did_activate_pending_tree_count_;
}
@@ -149,8 +132,8 @@ void SynchronousCompositorProxy::OnMessageReceived(
return;
IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorProxy, message)
- IPC_MESSAGE_HANDLER(SyncCompositorMsg_HandleInputEvent, HandleInputEvent)
- IPC_MESSAGE_HANDLER(SyncCompositorMsg_BeginFrame, BeginFrame)
+ IPC_MESSAGE_HANDLER(SyncCompositorMsg_SynchronizeRendererState,
+ PopulateCommonParams)
IPC_MESSAGE_HANDLER(SyncCompositorMsg_ComputeScroll, OnComputeScroll)
IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawHw,
DemandDrawHw)
@@ -158,7 +141,6 @@ void SynchronousCompositorProxy::OnMessageReceived(
IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZeroSharedMemory, ZeroSharedMemory)
IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawSw,
DemandDrawSw)
- IPC_MESSAGE_HANDLER(SyncCompositorMsg_UpdateState, ProcessCommonParams)
IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZoomBy, SynchronouslyZoomBy)
IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetScroll, SetScroll)
IPC_END_MESSAGE_MAP()
@@ -168,44 +150,13 @@ bool SynchronousCompositorProxy::Send(IPC::Message* message) {
return sender_->Send(message);
}
-void SynchronousCompositorProxy::HandleInputEvent(
- const SyncCompositorCommonBrowserParams& common_params,
- const blink::WebInputEvent* event,
- SyncCompositorCommonRendererParams* common_renderer_params,
- InputEventAckState* ack) {
- DCHECK(!inside_receive_);
- base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true);
-
- ProcessCommonParams(common_params);
- DCHECK(!input_handler_->is_null());
- ui::LatencyInfo latency;
- *ack = input_handler_->Run(routing_id_, event, &latency);
- PopulateCommonParams(common_renderer_params);
-}
-
-void SynchronousCompositorProxy::BeginFrame(
- const SyncCompositorCommonBrowserParams& common_params,
- const cc::BeginFrameArgs& args,
- SyncCompositorCommonRendererParams* common_renderer_params) {
- DCHECK(!inside_receive_);
- base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true);
-
- ProcessCommonParams(common_params);
- if (need_begin_frame_) {
- begin_frame_source_->BeginFrame(args);
- }
- PopulateCommonParams(common_renderer_params);
-}
-
void SynchronousCompositorProxy::DemandDrawHw(
- const SyncCompositorCommonBrowserParams& common_params,
const SyncCompositorDemandDrawHwParams& params,
IPC::Message* reply_message) {
DCHECK(!inside_receive_);
DCHECK(reply_message);
inside_receive_ = true;
- ProcessCommonParams(common_params);
if (output_surface_) {
base::AutoReset<IPC::Message*> scoped_hardware_draw_reply(
@@ -218,29 +169,28 @@ void SynchronousCompositorProxy::DemandDrawHw(
if (inside_receive_) {
// Did not swap.
- cc::CompositorFrame empty_frame;
- SendDemandDrawHwReply(&empty_frame, 0u, reply_message);
+ SendDemandDrawHwReply(cc::CompositorFrame(), 0u, reply_message);
inside_receive_ = false;
}
}
void SynchronousCompositorProxy::SwapBuffersHw(uint32_t output_surface_id,
- cc::CompositorFrame* frame) {
+ cc::CompositorFrame frame) {
DCHECK(inside_receive_);
DCHECK(hardware_draw_reply_);
- DCHECK(frame);
- SendDemandDrawHwReply(frame, output_surface_id, hardware_draw_reply_);
+ SendDemandDrawHwReply(std::move(frame), output_surface_id,
+ hardware_draw_reply_);
inside_receive_ = false;
}
void SynchronousCompositorProxy::SendDemandDrawHwReply(
- cc::CompositorFrame* frame,
+ cc::CompositorFrame frame,
uint32_t output_surface_id,
IPC::Message* reply_message) {
SyncCompositorCommonRendererParams common_renderer_params;
PopulateCommonParams(&common_renderer_params);
SyncCompositorMsg_DemandDrawHw::WriteReplyParams(
- reply_message, common_renderer_params, output_surface_id, *frame);
+ reply_message, common_renderer_params, output_surface_id, frame);
Send(reply_message);
}
@@ -254,7 +204,6 @@ struct SynchronousCompositorProxy::SharedMemoryWithSize {
};
void SynchronousCompositorProxy::SetSharedMemory(
- const SyncCompositorCommonBrowserParams& common_params,
const SyncCompositorSetSharedMemoryParams& params,
bool* success,
SyncCompositorCommonRendererParams* common_renderer_params) {
@@ -262,7 +211,6 @@ void SynchronousCompositorProxy::SetSharedMemory(
base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true);
*success = false;
- ProcessCommonParams(common_params);
if (!base::SharedMemory::IsHandleValid(params.shm_handle))
return;
@@ -276,18 +224,21 @@ void SynchronousCompositorProxy::SetSharedMemory(
}
void SynchronousCompositorProxy::ZeroSharedMemory() {
- DCHECK(!software_draw_shm_->zeroed);
+ // It is possible for this to get called twice, eg. if draw is called before
+ // the OutputSurface is ready. Just ignore duplicated calls rather than
+ // inventing a complicated system to avoid it.
+ if (software_draw_shm_->zeroed)
+ return;
+
memset(software_draw_shm_->shm.memory(), 0, software_draw_shm_->buffer_size);
software_draw_shm_->zeroed = true;
}
void SynchronousCompositorProxy::DemandDrawSw(
- const SyncCompositorCommonBrowserParams& common_params,
const SyncCompositorDemandDrawSwParams& params,
IPC::Message* reply_message) {
DCHECK(!inside_receive_);
inside_receive_ = true;
- ProcessCommonParams(common_params);
if (output_surface_) {
base::AutoReset<IPC::Message*> scoped_software_draw_reply(
&software_draw_reply_, reply_message);
@@ -302,8 +253,7 @@ void SynchronousCompositorProxy::DemandDrawSw(
}
if (inside_receive_) {
// Did not swap.
- cc::CompositorFrame empty_frame;
- SendDemandDrawSwReply(false, &empty_frame, reply_message);
+ SendDemandDrawSwReply(false, cc::CompositorFrame(), reply_message);
inside_receive_ = false;
}
}
@@ -330,40 +280,37 @@ void SynchronousCompositorProxy::DoDemandDrawSw(
output_surface_->DemandDrawSw(&canvas);
}
-void SynchronousCompositorProxy::SwapBuffersSw(cc::CompositorFrame* frame) {
+void SynchronousCompositorProxy::SwapBuffersSw(cc::CompositorFrame frame) {
DCHECK(inside_receive_);
DCHECK(software_draw_reply_);
- DCHECK(frame);
- SendDemandDrawSwReply(true, frame, software_draw_reply_);
+ SendDemandDrawSwReply(true, std::move(frame), software_draw_reply_);
inside_receive_ = false;
}
void SynchronousCompositorProxy::SendDemandDrawSwReply(
bool success,
- cc::CompositorFrame* frame,
+ cc::CompositorFrame frame,
IPC::Message* reply_message) {
SyncCompositorCommonRendererParams common_renderer_params;
PopulateCommonParams(&common_renderer_params);
SyncCompositorMsg_DemandDrawSw::WriteReplyParams(
- reply_message, success, common_renderer_params, *frame);
+ reply_message, success, common_renderer_params, frame);
Send(reply_message);
}
void SynchronousCompositorProxy::SwapBuffers(uint32_t output_surface_id,
- cc::CompositorFrame* frame) {
+ cc::CompositorFrame frame) {
DCHECK(hardware_draw_reply_ || software_draw_reply_);
DCHECK(!(hardware_draw_reply_ && software_draw_reply_));
if (hardware_draw_reply_) {
- SwapBuffersHw(output_surface_id, frame);
+ SwapBuffersHw(output_surface_id, std::move(frame));
} else if (software_draw_reply_) {
- SwapBuffersSw(frame);
+ SwapBuffersSw(std::move(frame));
}
}
void SynchronousCompositorProxy::OnComputeScroll(
- const SyncCompositorCommonBrowserParams& common_params,
base::TimeTicks animation_time) {
- ProcessCommonParams(common_params);
if (need_animate_scroll_) {
need_animate_scroll_ = false;
input_handler_proxy_->SynchronouslyAnimate(animation_time);
@@ -371,13 +318,11 @@ void SynchronousCompositorProxy::OnComputeScroll(
}
void SynchronousCompositorProxy::SynchronouslyZoomBy(
- const SyncCompositorCommonBrowserParams& common_params,
float zoom_delta,
const gfx::Point& anchor,
SyncCompositorCommonRendererParams* common_renderer_params) {
DCHECK(!inside_receive_);
base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true);
- ProcessCommonParams(common_params);
input_handler_proxy_->SynchronouslyZoomBy(zoom_delta, anchor);
PopulateCommonParams(common_renderer_params);
}
@@ -390,18 +335,4 @@ void SynchronousCompositorProxy::SetScroll(
input_handler_proxy_->SynchronouslySetRootScrollOffset(total_scroll_offset_);
}
-void SynchronousCompositorProxy::DidOverscroll(
- const DidOverscrollParams& did_overscroll_params) {
- SyncCompositorCommonRendererParams params;
- PopulateCommonParams(&params);
- Send(new SyncCompositorHostMsg_OverScroll(routing_id_, params,
- did_overscroll_params));
-}
-
-void SynchronousCompositorProxy::ProcessCommonParams(
- const SyncCompositorCommonBrowserParams& common_params) {
- begin_frame_source_->SetBeginFrameSourcePaused(
- common_params.begin_frame_source_paused);
-}
-
} // namespace content
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy.h b/chromium/content/renderer/android/synchronous_compositor_proxy.h
index d6f9e1ae996..6058aad9adc 100644
--- a/chromium/content/renderer/android/synchronous_compositor_proxy.h
+++ b/chromium/content/renderer/android/synchronous_compositor_proxy.h
@@ -10,9 +10,7 @@
#include "base/macros.h"
#include "content/common/input/input_event_ack_state.h"
-#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
#include "content/renderer/android/synchronous_compositor_output_surface.h"
-#include "content/renderer/input/input_handler_manager_client.h"
#include "ui/events/blink/synchronous_input_handler_proxy.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size_f.h"
@@ -35,7 +33,6 @@ class CompositorFrame;
namespace content {
class SynchronousCompositorOutputSurface;
-struct SyncCompositorCommonBrowserParams;
struct SyncCompositorCommonRendererParams;
struct SyncCompositorDemandDrawHwParams;
struct SyncCompositorDemandDrawSwParams;
@@ -43,15 +40,12 @@ struct SyncCompositorSetSharedMemoryParams;
class SynchronousCompositorProxy
: public ui::SynchronousInputHandler,
- public SynchronousCompositorExternalBeginFrameSourceClient,
public SynchronousCompositorOutputSurfaceClient {
public:
SynchronousCompositorProxy(
int routing_id,
IPC::Sender* sender,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- ui::SynchronousInputHandlerProxy* input_handler_proxy,
- InputHandlerManagerClient::Handler* handler);
+ ui::SynchronousInputHandlerProxy* input_handler_proxy);
~SynchronousCompositorProxy() override;
// ui::SynchronousInputHandler overrides.
@@ -63,73 +57,51 @@ class SynchronousCompositorProxy
float min_page_scale_factor,
float max_page_scale_factor) override;
- // SynchronousCompositorExternalBeginFrameSourceClient overrides.
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
// SynchronousCompositorOutputSurfaceClient overrides.
void DidActivatePendingTree() override;
void Invalidate() override;
void SwapBuffers(uint32_t output_surface_id,
- cc::CompositorFrame* frame) override;
+ cc::CompositorFrame frame) override;
void SetOutputSurface(SynchronousCompositorOutputSurface* output_surface);
void OnMessageReceived(const IPC::Message& message);
bool Send(IPC::Message* message);
- void DidOverscroll(const DidOverscrollParams& did_overscroll_params);
private:
struct SharedMemoryWithSize;
- void ProcessCommonParams(
- const SyncCompositorCommonBrowserParams& common_params);
- void PopulateCommonParams(SyncCompositorCommonRendererParams* params) const;
-
// IPC handlers.
- void HandleInputEvent(
- const SyncCompositorCommonBrowserParams& common_params,
- const blink::WebInputEvent* event,
- SyncCompositorCommonRendererParams* common_renderer_params,
- InputEventAckState* ack);
- void BeginFrame(const SyncCompositorCommonBrowserParams& common_params,
- const cc::BeginFrameArgs& args,
- SyncCompositorCommonRendererParams* common_renderer_params);
- void OnComputeScroll(const SyncCompositorCommonBrowserParams& common_params,
- base::TimeTicks animation_time);
- void DemandDrawHw(const SyncCompositorCommonBrowserParams& common_params,
- const SyncCompositorDemandDrawHwParams& params,
+ void PopulateCommonParams(SyncCompositorCommonRendererParams* params) const;
+ void OnComputeScroll(base::TimeTicks animation_time);
+ void DemandDrawHw(const SyncCompositorDemandDrawHwParams& params,
IPC::Message* reply_message);
void SetSharedMemory(
- const SyncCompositorCommonBrowserParams& common_params,
const SyncCompositorSetSharedMemoryParams& params,
bool* success,
SyncCompositorCommonRendererParams* common_renderer_params);
void ZeroSharedMemory();
- void DemandDrawSw(const SyncCompositorCommonBrowserParams& common_params,
- const SyncCompositorDemandDrawSwParams& params,
+ void DemandDrawSw(const SyncCompositorDemandDrawSwParams& params,
IPC::Message* reply_message);
void SynchronouslyZoomBy(
- const SyncCompositorCommonBrowserParams& common_params,
float zoom_delta,
const gfx::Point& anchor,
SyncCompositorCommonRendererParams* common_renderer_params);
void SetScroll(const gfx::ScrollOffset& total_scroll_offset);
- void SwapBuffersHw(uint32_t output_surface_id, cc::CompositorFrame* frame);
- void SendDemandDrawHwReply(cc::CompositorFrame* frame,
+ void SwapBuffersHw(uint32_t output_surface_id, cc::CompositorFrame frame);
+ void SendDemandDrawHwReply(cc::CompositorFrame frame,
uint32_t output_surface_id,
IPC::Message* reply_message);
void DoDemandDrawSw(const SyncCompositorDemandDrawSwParams& params);
- void SwapBuffersSw(cc::CompositorFrame* frame);
+ void SwapBuffersSw(cc::CompositorFrame frame);
void SendDemandDrawSwReply(bool success,
- cc::CompositorFrame* frame,
+ cc::CompositorFrame frame,
IPC::Message* reply_message);
void SendAsyncRendererStateIfNeeded();
const int routing_id_;
IPC::Sender* const sender_;
- SynchronousCompositorExternalBeginFrameSource* const begin_frame_source_;
ui::SynchronousInputHandlerProxy* const input_handler_proxy_;
- InputHandlerManagerClient::Handler* const input_handler_;
const bool use_in_process_zero_copy_software_draw_;
SynchronousCompositorOutputSurface* output_surface_;
bool inside_receive_;
@@ -149,7 +121,6 @@ class SynchronousCompositorProxy
float max_page_scale_factor_;
bool need_animate_scroll_;
uint32_t need_invalidate_count_;
- bool need_begin_frame_;
uint32_t did_activate_pending_tree_count_;
DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorProxy);
diff --git a/chromium/content/renderer/android/synchronous_compositor_registry.h b/chromium/content/renderer/android/synchronous_compositor_registry.h
index 381d394b78b..11ba68bd656 100644
--- a/chromium/content/renderer/android/synchronous_compositor_registry.h
+++ b/chromium/content/renderer/android/synchronous_compositor_registry.h
@@ -8,7 +8,6 @@
namespace content {
-class SynchronousCompositorExternalBeginFrameSource;
class SynchronousCompositorOutputSurface;
class SynchronousCompositorRegistry {
@@ -19,12 +18,6 @@ class SynchronousCompositorRegistry {
virtual void UnregisterOutputSurface(
int routing_id,
SynchronousCompositorOutputSurface* output_surface) = 0;
- virtual void RegisterBeginFrameSource(
- int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source) = 0;
- virtual void UnregisterBeginFrameSource(
- int routing_id,
- SynchronousCompositorExternalBeginFrameSource* begin_frame_source) = 0;
protected:
virtual ~SynchronousCompositorRegistry() {}
diff --git a/chromium/content/renderer/background_sync/background_sync_client_impl.h b/chromium/content/renderer/background_sync/background_sync_client_impl.h
index 921ca854ebd..a264ffc9514 100644
--- a/chromium/content/renderer/background_sync/background_sync_client_impl.h
+++ b/chromium/content/renderer/background_sync/background_sync_client_impl.h
@@ -26,8 +26,6 @@ class CONTENT_EXPORT BackgroundSyncClientImpl
~BackgroundSyncClientImpl() override;
private:
- using SyncCallback =
- mojo::Callback<void(blink::mojom::ServiceWorkerEventStatus)>;
explicit BackgroundSyncClientImpl(
mojo::InterfaceRequest<blink::mojom::BackgroundSyncServiceClient>
request);
diff --git a/chromium/content/renderer/bluetooth/bluetooth_dispatcher.cc b/chromium/content/renderer/bluetooth/bluetooth_dispatcher.cc
deleted file mode 100644
index 2ff8caaf74c..00000000000
--- a/chromium/content/renderer/bluetooth/bluetooth_dispatcher.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/bluetooth/bluetooth_dispatcher.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/lazy_instance.h"
-#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/common/bluetooth/bluetooth_messages.h"
-#include "device/bluetooth/bluetooth_uuid.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDeviceInit.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothRemoteGATTService.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h"
-
-using blink::WebBluetoothDeviceInit;
-using blink::WebBluetoothError;
-using blink::WebBluetoothRemoteGATTService;
-using blink::WebBluetoothReadValueCallbacks;
-using blink::WebBluetoothRequestDeviceCallbacks;
-using blink::WebBluetoothScanFilter;
-using blink::WebRequestDeviceOptions;
-using blink::WebString;
-using blink::WebVector;
-
-namespace content {
-
-namespace {
-
-base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls =
- LAZY_INSTANCE_INITIALIZER;
-
-void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1);
-
-int CurrentWorkerId() {
- return WorkerThread::GetCurrentId();
-}
-
-} // namespace
-
-BluetoothDispatcher::BluetoothDispatcher(ThreadSafeSender* sender)
- : thread_safe_sender_(sender) {
- g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this));
-}
-
-BluetoothDispatcher::~BluetoothDispatcher() {
- g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
-}
-
-BluetoothDispatcher* BluetoothDispatcher::GetOrCreateThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender) {
- if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
- NOTREACHED() << "Re-instantiating TLS BluetoothDispatcher.";
- g_dispatcher_tls.Pointer()->Set(NULL);
- }
- if (g_dispatcher_tls.Pointer()->Get())
- return static_cast<BluetoothDispatcher*>(g_dispatcher_tls.Pointer()->Get());
-
- BluetoothDispatcher* dispatcher = new BluetoothDispatcher(thread_safe_sender);
- if (CurrentWorkerId())
- WorkerThread::AddObserver(dispatcher);
- return dispatcher;
-}
-
-bool BluetoothDispatcher::Send(IPC::Message* msg) {
- return thread_safe_sender_->Send(msg);
-}
-
-void BluetoothDispatcher::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcher, msg)
- IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceSuccess,
- OnRequestDeviceSuccess);
- IPC_MESSAGE_HANDLER(BluetoothMsg_RequestDeviceError, OnRequestDeviceError);
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled) << "Unhandled message:" << msg.type();
-}
-
-void BluetoothDispatcher::requestDevice(
- int frame_routing_id,
- const WebRequestDeviceOptions& options,
- blink::WebBluetoothRequestDeviceCallbacks* callbacks) {
- int request_id = pending_requests_.Add(callbacks);
-
- // Convert |options| to its IPC form.
- std::vector<content::BluetoothScanFilter> filters(options.filters.size());
- for (size_t i = 0; i < options.filters.size(); ++i) {
- const WebBluetoothScanFilter& web_filter = options.filters[i];
- BluetoothScanFilter& filter = filters[i];
- filter.services.reserve(web_filter.services.size());
- for (const WebString& service : web_filter.services) {
- filter.services.push_back(device::BluetoothUUID(service.utf8()));
- }
- filter.name = web_filter.name.utf8();
- filter.namePrefix = web_filter.namePrefix.utf8();
- }
- std::vector<device::BluetoothUUID> optional_services;
- optional_services.reserve(options.optionalServices.size());
- for (const WebString& optional_service : options.optionalServices) {
- optional_services.push_back(device::BluetoothUUID(optional_service.utf8()));
- }
-
- Send(new BluetoothHostMsg_RequestDevice(CurrentWorkerId(), request_id,
- frame_routing_id, filters,
- optional_services));
-}
-
-void BluetoothDispatcher::WillStopCurrentWorkerThread() {
- delete this;
-}
-
-void BluetoothDispatcher::OnRequestDeviceSuccess(
- int thread_id,
- int request_id,
- const BluetoothDevice& device) {
- DCHECK(pending_requests_.Lookup(request_id)) << request_id;
-
- WebVector<WebString> uuids(device.uuids.size());
- for (size_t i = 0; i < device.uuids.size(); ++i)
- uuids[i] = WebString::fromUTF8(device.uuids[i].c_str());
-
- pending_requests_.Lookup(request_id)
- ->onSuccess(base::WrapUnique(new WebBluetoothDeviceInit(
- WebString::fromUTF8(device.id), WebString(device.name), uuids)));
- pending_requests_.Remove(request_id);
-}
-
-void BluetoothDispatcher::OnRequestDeviceError(int thread_id,
- int request_id,
- WebBluetoothError error) {
- DCHECK(pending_requests_.Lookup(request_id)) << request_id;
- pending_requests_.Lookup(request_id)->onError(WebBluetoothError(error));
- pending_requests_.Remove(request_id);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/bluetooth/bluetooth_dispatcher.h b/chromium/content/renderer/bluetooth/bluetooth_dispatcher.h
deleted file mode 100644
index e627d53ebdb..00000000000
--- a/chromium/content/renderer/bluetooth/bluetooth_dispatcher.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_
-#define CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <queue>
-
-#include "base/id_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/common/bluetooth/bluetooth_device.h"
-#include "content/public/child/worker_thread.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetooth.h"
-#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothError.h"
-
-namespace base {
-class MessageLoop;
-class TaskRunner;
-}
-
-namespace IPC {
-class Message;
-}
-
-namespace content {
-class ThreadSafeSender;
-
-// Dispatcher for child process threads which communicates to the browser's
-// BluetoothDispatcherHost.
-//
-// Instances are created for each thread as necessary by WebBluetoothImpl.
-//
-// Incoming IPC messages are received by the BluetoothMessageFilter and
-// directed to the thread specific instance of this class.
-// Outgoing messages come from WebBluetoothImpl.
-class BluetoothDispatcher : public WorkerThread::Observer {
- public:
- explicit BluetoothDispatcher(ThreadSafeSender* sender);
- ~BluetoothDispatcher() override;
-
- // Gets or Creates a BluetoothDispatcher for the current thread.
- // |thread_safe_sender| is required when constructing a BluetoothDispatcher.
- static BluetoothDispatcher* GetOrCreateThreadSpecificInstance(
- ThreadSafeSender* thread_safe_sender);
-
- // IPC Send and Receiving interface, see IPC::Sender and IPC::Listener.
- bool Send(IPC::Message* msg);
- void OnMessageReceived(const IPC::Message& msg);
-
- // Corresponding to WebBluetoothImpl methods.
- void requestDevice(int frame_routing_id,
- const blink::WebRequestDeviceOptions& options,
- blink::WebBluetoothRequestDeviceCallbacks* callbacks);
-
- // WorkerThread::Observer implementation.
- void WillStopCurrentWorkerThread() override;
-
- private:
- // IPC Handlers, see definitions in bluetooth_messages.h.
- void OnRequestDeviceSuccess(int thread_id,
- int request_id,
- const BluetoothDevice& device);
- void OnRequestDeviceError(int thread_id,
- int request_id,
- blink::WebBluetoothError error);
-
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
-
- // Tracks device requests sent to browser to match replies with callbacks.
- // Owns callback objects.
- IDMap<blink::WebBluetoothRequestDeviceCallbacks, IDMapOwnPointer>
- pending_requests_;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_BLUETOOTH_BLUETOOTH_DISPATCHER_H_
diff --git a/chromium/content/renderer/bluetooth/bluetooth_message_filter.cc b/chromium/content/renderer/bluetooth/bluetooth_message_filter.cc
deleted file mode 100644
index bd688da95c3..00000000000
--- a/chromium/content/renderer/bluetooth/bluetooth_message_filter.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/bluetooth/bluetooth_message_filter.h"
-
-#include "content/child/thread_safe_sender.h"
-#include "content/renderer/bluetooth/bluetooth_dispatcher.h"
-#include "ipc/ipc_message_macros.h"
-
-namespace content {
-
-BluetoothMessageFilter::BluetoothMessageFilter(ThreadSafeSender* sender)
- : WorkerThreadMessageFilter(sender) {
-}
-
-BluetoothMessageFilter::~BluetoothMessageFilter() {
-}
-
-bool BluetoothMessageFilter::ShouldHandleMessage(
- const IPC::Message& msg) const {
- return IPC_MESSAGE_CLASS(msg) == BluetoothMsgStart;
-}
-
-void BluetoothMessageFilter::OnFilteredMessageReceived(
- const IPC::Message& msg) {
- BluetoothDispatcher::GetOrCreateThreadSpecificInstance(thread_safe_sender())
- ->OnMessageReceived(msg);
-}
-
-bool BluetoothMessageFilter::GetWorkerThreadIdForMessage(
- const IPC::Message& msg,
- int* ipc_thread_id) {
- return base::PickleIterator(msg).ReadInt(ipc_thread_id);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/bluetooth/bluetooth_message_filter.h b/chromium/content/renderer/bluetooth/bluetooth_message_filter.h
deleted file mode 100644
index 365e21aeb71..00000000000
--- a/chromium/content/renderer/bluetooth/bluetooth_message_filter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_
-#define CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_
-
-#include "base/macros.h"
-#include "content/child/worker_thread_message_filter.h"
-
-namespace content {
-
-class BluetoothMessageFilter : public WorkerThreadMessageFilter {
- public:
- explicit BluetoothMessageFilter(ThreadSafeSender* thread_safe_sender);
-
- private:
- ~BluetoothMessageFilter() override;
-
- // WorkerThreadMessageFilter:
- bool ShouldHandleMessage(const IPC::Message& msg) const override;
- void OnFilteredMessageReceived(const IPC::Message& msg) override;
- bool GetWorkerThreadIdForMessage(const IPC::Message& msg,
- int* ipc_thread_id) override;
-
- DISALLOW_COPY_AND_ASSIGN(BluetoothMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_
diff --git a/chromium/content/renderer/bluetooth/bluetooth_type_converters.cc b/chromium/content/renderer/bluetooth/bluetooth_type_converters.cc
new file mode 100644
index 00000000000..c7bf1a79489
--- /dev/null
+++ b/chromium/content/renderer/bluetooth/bluetooth_type_converters.cc
@@ -0,0 +1,60 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/bluetooth/bluetooth_type_converters.h"
+
+#include "content/child/mojo/type_converters.h"
+#include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h"
+
+namespace mojo {
+
+// static
+blink::mojom::WebBluetoothScanFilterPtr TypeConverter<
+ blink::mojom::WebBluetoothScanFilterPtr,
+ blink::WebBluetoothScanFilter>::Convert(const blink::WebBluetoothScanFilter&
+ web_filter) {
+ blink::mojom::WebBluetoothScanFilterPtr filter =
+ blink::mojom::WebBluetoothScanFilter::New();
+
+ if (!web_filter.services.isEmpty())
+ filter->services =
+ Array<base::Optional<device::BluetoothUUID>>::From(web_filter.services);
+
+ if (web_filter.hasName)
+ filter->name = String::From(web_filter.name);
+
+ if (!web_filter.namePrefix.isEmpty())
+ filter->name_prefix = String::From(web_filter.namePrefix);
+ return filter;
+}
+
+// static
+blink::mojom::WebBluetoothRequestDeviceOptionsPtr
+TypeConverter<blink::mojom::WebBluetoothRequestDeviceOptionsPtr,
+ blink::WebRequestDeviceOptions>::
+ Convert(const blink::WebRequestDeviceOptions& web_options) {
+ blink::mojom::WebBluetoothRequestDeviceOptionsPtr options =
+ blink::mojom::WebBluetoothRequestDeviceOptions::New();
+
+ options->filters = mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>::From(
+ web_options.filters);
+ options->optional_services =
+ mojo::Array<base::Optional<device::BluetoothUUID>>::From(
+ web_options.optionalServices);
+ return options;
+}
+
+// static
+base::Optional<device::BluetoothUUID>
+TypeConverter<base::Optional<device::BluetoothUUID>, blink::WebString>::Convert(
+ const blink::WebString& web_string) {
+ base::Optional<device::BluetoothUUID> uuid =
+ device::BluetoothUUID(web_string.utf8());
+
+ DCHECK(uuid->IsValid());
+
+ return uuid;
+}
+
+} // namespace mojo
diff --git a/chromium/content/renderer/bluetooth/bluetooth_type_converters.h b/chromium/content/renderer/bluetooth/bluetooth_type_converters.h
new file mode 100644
index 00000000000..2b6e5263d4f
--- /dev/null
+++ b/chromium/content/renderer/bluetooth/bluetooth_type_converters.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_
+#define CONTENT_RENDERER_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_
+
+#include "base/optional.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom.h"
+
+namespace blink {
+struct WebBluetoothScanFilter;
+struct WebRequestDeviceOptions;
+}
+
+namespace mojo {
+
+template <>
+struct TypeConverter<blink::mojom::WebBluetoothScanFilterPtr,
+ blink::WebBluetoothScanFilter> {
+ static blink::mojom::WebBluetoothScanFilterPtr Convert(
+ const blink::WebBluetoothScanFilter& web_filter);
+};
+
+template <>
+struct TypeConverter<blink::mojom::WebBluetoothRequestDeviceOptionsPtr,
+ blink::WebRequestDeviceOptions> {
+ static blink::mojom::WebBluetoothRequestDeviceOptionsPtr Convert(
+ const blink::WebRequestDeviceOptions& web_options);
+};
+
+template <>
+struct TypeConverter<base::Optional<device::BluetoothUUID>, blink::WebString> {
+ static base::Optional<device::BluetoothUUID> Convert(
+ const blink::WebString& web_string);
+};
+
+} // namespace mojo
+
+#endif // CONTENT_RENDERER_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_
diff --git a/chromium/content/renderer/bluetooth/web_bluetooth_impl.cc b/chromium/content/renderer/bluetooth/web_bluetooth_impl.cc
index 2f4da53dcdf..f245362d225 100644
--- a/chromium/content/renderer/bluetooth/web_bluetooth_impl.cc
+++ b/chromium/content/renderer/bluetooth/web_bluetooth_impl.cc
@@ -9,26 +9,24 @@
#include <vector>
#include "base/memory/ptr_util.h"
+#include "base/optional.h"
#include "content/child/mojo/type_converters.h"
#include "content/child/thread_safe_sender.h"
-#include "content/public/common/service_registry.h"
-#include "content/renderer/bluetooth/bluetooth_dispatcher.h"
+#include "content/renderer/bluetooth/bluetooth_type_converters.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/array.h"
+#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDevice.h"
+#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothDeviceInit.h"
#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothRemoteGATTCharacteristic.h"
#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothRemoteGATTCharacteristicInit.h"
#include "third_party/WebKit/public/platform/modules/bluetooth/WebBluetoothRemoteGATTService.h"
+#include "third_party/WebKit/public/platform/modules/bluetooth/WebRequestDeviceOptions.h"
namespace content {
-WebBluetoothImpl::WebBluetoothImpl(ServiceRegistry* service_registry,
- ThreadSafeSender* thread_safe_sender,
- int frame_routing_id)
- : service_registry_(service_registry),
- binding_(this),
- thread_safe_sender_(thread_safe_sender),
- frame_routing_id_(frame_routing_id) {}
+WebBluetoothImpl::WebBluetoothImpl(shell::InterfaceProvider* remote_interfaces)
+ : remote_interfaces_(remote_interfaces), binding_(this) {}
WebBluetoothImpl::~WebBluetoothImpl() {
}
@@ -36,7 +34,11 @@ WebBluetoothImpl::~WebBluetoothImpl() {
void WebBluetoothImpl::requestDevice(
const blink::WebRequestDeviceOptions& options,
blink::WebBluetoothRequestDeviceCallbacks* callbacks) {
- GetDispatcher()->requestDevice(frame_routing_id_, options, callbacks);
+ GetWebBluetoothService().RequestDevice(
+ blink::mojom::WebBluetoothRequestDeviceOptions::From(options),
+ base::Bind(&WebBluetoothImpl::OnRequestDeviceComplete,
+ base::Unretained(this),
+ base::Passed(base::WrapUnique(callbacks))));
}
void WebBluetoothImpl::connect(
@@ -60,13 +62,18 @@ void WebBluetoothImpl::disconnect(const blink::WebString& device_id) {
mojo::String::From(device_id));
}
-void WebBluetoothImpl::getPrimaryService(
+void WebBluetoothImpl::getPrimaryServices(
const blink::WebString& device_id,
- const blink::WebString& service_uuid,
- blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) {
- GetWebBluetoothService().RemoteServerGetPrimaryService(
- mojo::String::From(device_id), mojo::String::From(service_uuid),
- base::Bind(&WebBluetoothImpl::OnGetPrimaryServiceComplete,
+
+ blink::mojom::WebBluetoothGATTQueryQuantity quantity,
+ const blink::WebString& services_uuid,
+ blink::WebBluetoothGetPrimaryServicesCallbacks* callbacks) {
+ GetWebBluetoothService().RemoteServerGetPrimaryServices(
+ mojo::String::From(device_id), quantity,
+ services_uuid.isEmpty()
+ ? base::nullopt
+ : base::make_optional(device::BluetoothUUID(services_uuid.utf8())),
+ base::Bind(&WebBluetoothImpl::OnGetPrimaryServicesComplete,
base::Unretained(this), device_id,
base::Passed(base::WrapUnique(callbacks))));
}
@@ -78,8 +85,10 @@ void WebBluetoothImpl::getCharacteristics(
blink::WebBluetoothGetCharacteristicsCallbacks* callbacks) {
GetWebBluetoothService().RemoteServiceGetCharacteristics(
mojo::String::From(service_instance_id), quantity,
- characteristics_uuid.isEmpty() ? nullptr
- : mojo::String::From(characteristics_uuid),
+ characteristics_uuid.isEmpty()
+ ? base::nullopt
+ : base::make_optional(
+ device::BluetoothUUID(characteristics_uuid.utf8())),
base::Bind(&WebBluetoothImpl::OnGetCharacteristicsComplete,
base::Unretained(this), service_instance_id,
base::Passed(base::WrapUnique(callbacks))));
@@ -154,11 +163,32 @@ void WebBluetoothImpl::RemoteCharacteristicValueChanged(
value.PassStorage()));
}
+void WebBluetoothImpl::OnRequestDeviceComplete(
+ std::unique_ptr<blink::WebBluetoothRequestDeviceCallbacks> callbacks,
+ const blink::mojom::WebBluetoothError error,
+ blink::mojom::WebBluetoothDevicePtr device) {
+ if (error == blink::mojom::WebBluetoothError::SUCCESS) {
+ blink::WebVector<blink::WebString> uuids(device->uuids.size());
+ for (size_t i = 0; i < device->uuids.size(); ++i)
+ uuids[i] = blink::WebString::fromUTF8(device->uuids[i]);
+
+ callbacks->onSuccess(base::WrapUnique(new blink::WebBluetoothDeviceInit(
+ blink::WebString::fromUTF8(device->id),
+ blink::WebString::fromUTF8(device->name), uuids)));
+ } else {
+ callbacks->onError(error);
+ }
+}
+
void WebBluetoothImpl::GattServerDisconnected(const mojo::String& device_id) {
auto device_iter = connected_devices_.find(device_id);
if (device_iter != connected_devices_.end()) {
- device_iter->second->dispatchGattServerDisconnected();
+ // Remove device from the map before calling dispatchGattServerDisconnected
+ // to avoid removing a device the gattserverdisconnected event handler might
+ // have re-connected.
+ blink::WebBluetoothDevice* device = device_iter->second;
connected_devices_.erase(device_iter);
+ device->dispatchGattServerDisconnected();
}
}
@@ -173,17 +203,23 @@ void WebBluetoothImpl::OnConnectComplete(
}
}
-void WebBluetoothImpl::OnGetPrimaryServiceComplete(
+void WebBluetoothImpl::OnGetPrimaryServicesComplete(
const blink::WebString& device_id,
- std::unique_ptr<blink::WebBluetoothGetPrimaryServiceCallbacks> callbacks,
+ std::unique_ptr<blink::WebBluetoothGetPrimaryServicesCallbacks> callbacks,
blink::mojom::WebBluetoothError error,
- blink::mojom::WebBluetoothRemoteGATTServicePtr service) {
+ mojo::Array<blink::mojom::WebBluetoothRemoteGATTServicePtr> services) {
if (error == blink::mojom::WebBluetoothError::SUCCESS) {
- callbacks->onSuccess(
- base::WrapUnique(new blink::WebBluetoothRemoteGATTService(
- blink::WebString::fromUTF8(service->instance_id),
- blink::WebString::fromUTF8(service->uuid), true /* isPrimary */,
- device_id)));
+ // TODO(dcheng): This WebVector should use smart pointers.
+ blink::WebVector<blink::WebBluetoothRemoteGATTService*> promise_services(
+ services.size());
+
+ for (size_t i = 0; i < services.size(); i++) {
+ promise_services[i] = new blink::WebBluetoothRemoteGATTService(
+ blink::WebString::fromUTF8(services[i]->instance_id),
+ blink::WebString::fromUTF8(services[i]->uuid), true /* isPrimary */,
+ device_id);
+ }
+ callbacks->onSuccess(promise_services);
} else {
callbacks->onError(error);
}
@@ -260,15 +296,9 @@ void WebBluetoothImpl::DispatchCharacteristicValueChanged(
}
}
-BluetoothDispatcher* WebBluetoothImpl::GetDispatcher() {
- return BluetoothDispatcher::GetOrCreateThreadSpecificInstance(
- thread_safe_sender_.get());
-}
-
blink::mojom::WebBluetoothService& WebBluetoothImpl::GetWebBluetoothService() {
if (!web_bluetooth_service_) {
- service_registry_->ConnectToRemoteService(
- mojo::GetProxy(&web_bluetooth_service_));
+ remote_interfaces_->GetInterface(mojo::GetProxy(&web_bluetooth_service_));
// Create an associated interface ptr and pass it to the WebBluetoothService
// so that it can send us events without us prompting.
blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo ptr_info;
diff --git a/chromium/content/renderer/bluetooth/web_bluetooth_impl.h b/chromium/content/renderer/bluetooth/web_bluetooth_impl.h
index fae4ad485ee..13d7c7b9a18 100644
--- a/chromium/content/renderer/bluetooth/web_bluetooth_impl.h
+++ b/chromium/content/renderer/bluetooth/web_bluetooth_impl.h
@@ -25,11 +25,14 @@ namespace blink {
class WebBluetoothRemoteGATTCharacteristic;
}
+namespace shell {
+class InterfaceProvider;
+}
+
namespace content {
class BluetoothDispatcher;
class ThreadSafeSender;
-class ServiceRegistry;
// Implementation of blink::WebBluetooth. Passes calls through to the thread
// specific BluetoothDispatcher.
@@ -37,9 +40,7 @@ class CONTENT_EXPORT WebBluetoothImpl
: NON_EXPORTED_BASE(public blink::mojom::WebBluetoothServiceClient),
NON_EXPORTED_BASE(public blink::WebBluetooth) {
public:
- WebBluetoothImpl(ServiceRegistry* service_registry,
- ThreadSafeSender* thread_safe_sender,
- int frame_routing_id);
+ WebBluetoothImpl(shell::InterfaceProvider* remote_interfaces);
~WebBluetoothImpl() override;
// blink::WebBluetooth interface:
@@ -51,10 +52,11 @@ class CONTENT_EXPORT WebBluetoothImpl
blink::WebBluetoothDevice* device,
blink::WebBluetoothRemoteGATTServerConnectCallbacks* callbacks) override;
void disconnect(const blink::WebString& device_id) override;
- void getPrimaryService(
+ void getPrimaryServices(
const blink::WebString& device_id,
- const blink::WebString& service_uuid,
- blink::WebBluetoothGetPrimaryServiceCallbacks* callbacks) override;
+ blink::mojom::WebBluetoothGATTQueryQuantity quantity,
+ const blink::WebString& services_uuid,
+ blink::WebBluetoothGetPrimaryServicesCallbacks* callbacks) override;
void getCharacteristics(
const blink::WebString& service_instance_id,
blink::mojom::WebBluetoothGATTQueryQuantity quantity,
@@ -87,15 +89,19 @@ class CONTENT_EXPORT WebBluetoothImpl
void GattServerDisconnected(const mojo::String& device_id) override;
// Callbacks for WebBluetoothService calls:
+ void OnRequestDeviceComplete(
+ std::unique_ptr<blink::WebBluetoothRequestDeviceCallbacks> callbacks,
+ const blink::mojom::WebBluetoothError error,
+ blink::mojom::WebBluetoothDevicePtr device);
void OnConnectComplete(
std::unique_ptr<blink::WebBluetoothRemoteGATTServerConnectCallbacks>
callbacks,
blink::mojom::WebBluetoothError error);
- void OnGetPrimaryServiceComplete(
+ void OnGetPrimaryServicesComplete(
const blink::WebString& device_id,
- std::unique_ptr<blink::WebBluetoothGetPrimaryServiceCallbacks> callbacks,
+ std::unique_ptr<blink::WebBluetoothGetPrimaryServicesCallbacks> callbacks,
blink::mojom::WebBluetoothError error,
- blink::mojom::WebBluetoothRemoteGATTServicePtr service);
+ mojo::Array<blink::mojom::WebBluetoothRemoteGATTServicePtr> services);
void OnGetCharacteristicsComplete(
const blink::WebString& service_instance_id,
std::unique_ptr<blink::WebBluetoothGetCharacteristicsCallbacks> callbacks,
@@ -120,10 +126,8 @@ class CONTENT_EXPORT WebBluetoothImpl
const std::string& characteristic_instance_id,
const std::vector<uint8_t>& value);
- BluetoothDispatcher* GetDispatcher();
-
blink::mojom::WebBluetoothService& GetWebBluetoothService();
- ServiceRegistry* const service_registry_;
+ shell::InterfaceProvider* const remote_interfaces_;
blink::mojom::WebBluetoothServicePtr web_bluetooth_service_;
// Map of characteristic_instance_ids to
@@ -142,9 +146,6 @@ class CONTENT_EXPORT WebBluetoothImpl
// Binding associated with |web_bluetooth_service_|.
mojo::AssociatedBinding<blink::mojom::WebBluetoothServiceClient> binding_;
- const scoped_refptr<ThreadSafeSender> thread_safe_sender_;
- const int frame_routing_id_;
-
DISALLOW_COPY_AND_ASSIGN(WebBluetoothImpl);
};
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc
index 76e71752418..75d15c837cc 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.cc
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc
@@ -325,7 +325,7 @@ void BrowserPlugin::destroy() {
render_frame ? render_frame->GetRenderView() : nullptr);
if (render_view)
render_view->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
v8::Local<v8::Object> BrowserPlugin::v8ScriptableObject(v8::Isolate* isolate) {
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h
index 6cd8bebea23..99092e4ba99 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.h
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.h
@@ -23,7 +23,7 @@ struct BrowserPluginHostMsg_ResizeGuest_Params;
struct FrameMsg_BuffersSwapped_Params;
namespace cc {
-struct SurfaceId;
+class SurfaceId;
struct SurfaceSequence;
}
diff --git a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
index 5bc3521dea1..a490e4c69b5 100644
--- a/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
+++ b/chromium/content/renderer/cache_storage/cache_storage_dispatcher.cc
@@ -82,6 +82,9 @@ ServiceWorkerResponse ResponseFromWebResponse(
const blink::WebServiceWorkerResponse& web_response) {
ServiceWorkerHeaderMap headers;
GetServiceWorkerHeaderMapFromWebResponse(web_response, &headers);
+ ServiceWorkerHeaderList cors_exposed_header_names;
+ GetCorsExposedHeaderNamesFromWebResponse(web_response,
+ &cors_exposed_header_names);
// We don't support streaming for cache.
DCHECK(web_response.streamURL().isEmpty());
return ServiceWorkerResponse(
@@ -93,7 +96,7 @@ ServiceWorkerResponse ResponseFromWebResponse(
blink::WebServiceWorkerResponseErrorUnknown,
base::Time::FromInternalValue(web_response.responseTime()),
!web_response.cacheStorageCacheName().isNull(),
- web_response.cacheStorageCacheName().utf8());
+ web_response.cacheStorageCacheName().utf8(), cors_exposed_header_names);
}
CacheStorageCacheQueryParams QueryParamsFromWebQueryParams(
@@ -655,6 +658,13 @@ void CacheStorageDispatcher::PopulateWebResponseFromResponse(
response.is_in_cache_storage
? blink::WebString::fromUTF8(response.cache_storage_cache_name)
: blink::WebString());
+ blink::WebVector<blink::WebString> headers(
+ response.cors_exposed_header_names.size());
+ std::transform(
+ response.cors_exposed_header_names.begin(),
+ response.cors_exposed_header_names.end(), headers.begin(),
+ [](const std::string& h) { return blink::WebString::fromLatin1(h); });
+ web_response->setCorsExposedHeaderNames(headers);
for (const auto& i : response.headers) {
web_response->setHeader(base::ASCIIToUTF16(i.first),
diff --git a/chromium/content/renderer/raster_worker_pool.cc b/chromium/content/renderer/categorized_worker_pool.cc
index 8c50e01b3b9..41814b4bcd3 100644
--- a/chromium/content/renderer/raster_worker_pool.cc
+++ b/chromium/content/renderer/categorized_worker_pool.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/raster_worker_pool.h"
+#include "content/renderer/categorized_worker_pool.h"
#include <string>
#include <utility>
@@ -17,15 +17,16 @@
namespace content {
namespace {
-// A thread which forwards to RasterWorkerPool::Run with the runnable
+// A thread which forwards to CategorizedWorkerPool::Run with the runnable
// categories.
-class RasterWorkerPoolThread : public base::SimpleThread {
+class CategorizedWorkerPoolThread : public base::SimpleThread {
public:
- RasterWorkerPoolThread(const std::string& name_prefix,
- const Options& options,
- RasterWorkerPool* pool,
- std::vector<cc::TaskCategory> categories,
- base::ConditionVariable* has_ready_to_run_tasks_cv)
+ CategorizedWorkerPoolThread(
+ const std::string& name_prefix,
+ const Options& options,
+ CategorizedWorkerPool* pool,
+ std::vector<cc::TaskCategory> categories,
+ base::ConditionVariable* has_ready_to_run_tasks_cv)
: SimpleThread(name_prefix, options),
pool_(pool),
categories_(categories),
@@ -34,18 +35,18 @@ class RasterWorkerPoolThread : public base::SimpleThread {
void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); }
private:
- RasterWorkerPool* const pool_;
+ CategorizedWorkerPool* const pool_;
const std::vector<cc::TaskCategory> categories_;
base::ConditionVariable* const has_ready_to_run_tasks_cv_;
};
} // namespace
-// A sequenced task runner which posts tasks to a RasterWorkerPool.
-class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
+// A sequenced task runner which posts tasks to a CategorizedWorkerPool.
+class CategorizedWorkerPool::CategorizedWorkerPoolSequencedTaskRunner
: public base::SequencedTaskRunner {
public:
- explicit RasterWorkerPoolSequencedTaskRunner(
+ explicit CategorizedWorkerPoolSequencedTaskRunner(
cc::TaskGraphRunner* task_graph_runner)
: task_graph_runner_(task_graph_runner),
namespace_token_(task_graph_runner->GetNamespaceToken()) {}
@@ -95,7 +96,7 @@ class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
}
private:
- ~RasterWorkerPoolSequencedTaskRunner() override {
+ ~CategorizedWorkerPoolSequencedTaskRunner() override {
task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
task_graph_runner_->CollectCompletedTasks(namespace_token_,
&completed_tasks_);
@@ -117,14 +118,14 @@ class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
cc::Task::Vector completed_tasks_;
};
-RasterWorkerPool::RasterWorkerPool()
+CategorizedWorkerPool::CategorizedWorkerPool()
: namespace_token_(GetNamespaceToken()),
has_ready_to_run_foreground_tasks_cv_(&lock_),
has_ready_to_run_background_tasks_cv_(&lock_),
has_namespaces_with_finished_running_tasks_cv_(&lock_),
shutdown_(false) {}
-void RasterWorkerPool::Start(int num_threads) {
+void CategorizedWorkerPool::Start(int num_threads) {
DCHECK(threads_.empty());
// Start |num_threads| threads for foreground work, including nonconcurrent
@@ -134,7 +135,7 @@ void RasterWorkerPool::Start(int num_threads) {
foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND);
for (int i = 0; i < num_threads; i++) {
- std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
+ std::unique_ptr<base::SimpleThread> thread(new CategorizedWorkerPoolThread(
base::StringPrintf("CompositorTileWorker%u",
static_cast<unsigned>(threads_.size() + 1))
.c_str(),
@@ -154,14 +155,14 @@ void RasterWorkerPool::Start(int num_threads) {
thread_options.set_priority(base::ThreadPriority::BACKGROUND);
#endif
- std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread(
+ std::unique_ptr<base::SimpleThread> thread(new CategorizedWorkerPoolThread(
"CompositorTileWorkerBackground", thread_options, this,
background_categories, &has_ready_to_run_background_tasks_cv_));
thread->Start();
threads_.push_back(std::move(thread));
}
-void RasterWorkerPool::Shutdown() {
+void CategorizedWorkerPool::Shutdown() {
WaitForTasksToFinishRunning(namespace_token_);
CollectCompletedTasks(namespace_token_, &completed_tasks_);
// Shutdown raster threads.
@@ -185,7 +186,7 @@ void RasterWorkerPool::Shutdown() {
}
// Overridden from base::TaskRunner:
-bool RasterWorkerPool::PostDelayedTask(
+bool CategorizedWorkerPool::PostDelayedTask(
const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
@@ -218,12 +219,13 @@ bool RasterWorkerPool::PostDelayedTask(
return true;
}
-bool RasterWorkerPool::RunsTasksOnCurrentThread() const {
+bool CategorizedWorkerPool::RunsTasksOnCurrentThread() const {
return true;
}
-void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories,
- base::ConditionVariable* has_ready_to_run_tasks_cv) {
+void CategorizedWorkerPool::Run(
+ const std::vector<cc::TaskCategory>& categories,
+ base::ConditionVariable* has_ready_to_run_tasks_cv) {
base::AutoLock lock(lock_);
while (true) {
@@ -243,7 +245,7 @@ void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories,
}
}
-void RasterWorkerPool::FlushForTesting() {
+void CategorizedWorkerPool::FlushForTesting() {
base::AutoLock lock(lock_);
while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) {
@@ -252,21 +254,21 @@ void RasterWorkerPool::FlushForTesting() {
}
scoped_refptr<base::SequencedTaskRunner>
-RasterWorkerPool::CreateSequencedTaskRunner() {
- return new RasterWorkerPoolSequencedTaskRunner(this);
+CategorizedWorkerPool::CreateSequencedTaskRunner() {
+ return new CategorizedWorkerPoolSequencedTaskRunner(this);
}
-RasterWorkerPool::~RasterWorkerPool() {}
+CategorizedWorkerPool::~CategorizedWorkerPool() {}
-cc::NamespaceToken RasterWorkerPool::GetNamespaceToken() {
+cc::NamespaceToken CategorizedWorkerPool::GetNamespaceToken() {
base::AutoLock lock(lock_);
return work_queue_.GetNamespaceToken();
}
-void RasterWorkerPool::ScheduleTasks(cc::NamespaceToken token,
- cc::TaskGraph* graph) {
+void CategorizedWorkerPool::ScheduleTasks(cc::NamespaceToken token,
+ cc::TaskGraph* graph) {
TRACE_EVENT2("disabled-by-default-cc.debug",
- "RasterWorkerPool::ScheduleTasks", "num_nodes",
+ "CategorizedWorkerPool::ScheduleTasks", "num_nodes",
graph->nodes.size(), "num_edges", graph->edges.size());
{
base::AutoLock lock(lock_);
@@ -274,8 +276,9 @@ void RasterWorkerPool::ScheduleTasks(cc::NamespaceToken token,
}
}
-void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token,
- cc::TaskGraph* graph) {
+void CategorizedWorkerPool::ScheduleTasksWithLockAcquired(
+ cc::NamespaceToken token,
+ cc::TaskGraph* graph) {
DCHECK(token.IsValid());
DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph));
DCHECK(!shutdown_);
@@ -286,9 +289,10 @@ void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token,
SignalHasReadyToRunTasksWithLockAcquired();
}
-void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) {
+void CategorizedWorkerPool::WaitForTasksToFinishRunning(
+ cc::NamespaceToken token) {
TRACE_EVENT0("disabled-by-default-cc.debug",
- "RasterWorkerPool::WaitForTasksToFinishRunning");
+ "CategorizedWorkerPool::WaitForTasksToFinishRunning");
DCHECK(token.IsValid());
@@ -310,11 +314,11 @@ void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) {
}
}
-void RasterWorkerPool::CollectCompletedTasks(
+void CategorizedWorkerPool::CollectCompletedTasks(
cc::NamespaceToken token,
cc::Task::Vector* completed_tasks) {
TRACE_EVENT0("disabled-by-default-cc.debug",
- "RasterWorkerPool::CollectCompletedTasks");
+ "CategorizedWorkerPool::CollectCompletedTasks");
{
base::AutoLock lock(lock_);
@@ -322,14 +326,14 @@ void RasterWorkerPool::CollectCompletedTasks(
}
}
-void RasterWorkerPool::CollectCompletedTasksWithLockAcquired(
+void CategorizedWorkerPool::CollectCompletedTasksWithLockAcquired(
cc::NamespaceToken token,
cc::Task::Vector* completed_tasks) {
DCHECK(token.IsValid());
work_queue_.CollectCompletedTasks(token, completed_tasks);
}
-bool RasterWorkerPool::RunTaskWithLockAcquired(
+bool CategorizedWorkerPool::RunTaskWithLockAcquired(
const std::vector<cc::TaskCategory>& categories) {
for (const auto& category : categories) {
if (ShouldRunTaskForCategoryWithLockAcquired(category)) {
@@ -340,7 +344,7 @@ bool RasterWorkerPool::RunTaskWithLockAcquired(
return false;
}
-void RasterWorkerPool::RunTaskInCategoryWithLockAcquired(
+void CategorizedWorkerPool::RunTaskInCategoryWithLockAcquired(
cc::TaskCategory category) {
TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask");
@@ -366,7 +370,7 @@ void RasterWorkerPool::RunTaskInCategoryWithLockAcquired(
has_namespaces_with_finished_running_tasks_cv_.Signal();
}
-bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired(
+bool CategorizedWorkerPool::ShouldRunTaskForCategoryWithLockAcquired(
cc::TaskCategory category) {
lock_.AssertAcquired();
@@ -399,7 +403,7 @@ bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired(
return true;
}
-void RasterWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() {
+void CategorizedWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() {
lock_.AssertAcquired();
if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_FOREGROUND) ||
@@ -413,15 +417,15 @@ void RasterWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() {
}
}
-RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure)
+CategorizedWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure)
: closure_(closure) {}
// Overridden from cc::Task:
-void RasterWorkerPool::ClosureTask::RunOnWorkerThread() {
+void CategorizedWorkerPool::ClosureTask::RunOnWorkerThread() {
closure_.Run();
closure_.Reset();
}
-RasterWorkerPool::ClosureTask::~ClosureTask() {}
+CategorizedWorkerPool::ClosureTask::~ClosureTask() {}
} // namespace content
diff --git a/chromium/content/renderer/raster_worker_pool.h b/chromium/content/renderer/categorized_worker_pool.h
index 10c312be68b..2f75f2183f2 100644
--- a/chromium/content/renderer/raster_worker_pool.h
+++ b/chromium/content/renderer/categorized_worker_pool.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_RASTER_WORKER_POOL_H_
-#define CONTENT_RENDERER_RASTER_WORKER_POOL_H_
+#ifndef CONTENT_RENDERER_CATEGORIZED_WORKER_POOL_H_
+#define CONTENT_RENDERER_CATEGORIZED_WORKER_POOL_H_
#include <memory>
@@ -21,18 +21,18 @@
namespace content {
-// A pool of threads used to run raster work.
-// Work can be scheduled on the threads using different interfaces.
-// The pool itself implements TaskRunner interface and tasks posted via that
-// interface might run in parallel.
-// CreateSequencedTaskRunner creates a sequenced task runner that might run in
-// parallel with other instances of sequenced task runners.
-// It's also possible to get the underlying TaskGraphRunner to schedule a graph
-// of tasks with their dependencies.
-class CONTENT_EXPORT RasterWorkerPool : public base::TaskRunner,
- public cc::TaskGraphRunner {
+// A pool of threads used to run categorized work. The work can be scheduled on
+// the threads using different interfaces.
+// 1. The pool itself implements TaskRunner interface and tasks posted via that
+// interface might run in parallel.
+// 2. The pool also implements TaskGraphRunner interface which allows to
+// schedule a graph of tasks with their dependencies.
+// 3. CreateSequencedTaskRunner() creates a sequenced task runner that might run
+// in parallel with other instances of sequenced task runners.
+class CONTENT_EXPORT CategorizedWorkerPool : public base::TaskRunner,
+ public cc::TaskGraphRunner {
public:
- RasterWorkerPool();
+ CategorizedWorkerPool();
// Overridden from base::TaskRunner:
bool PostDelayedTask(const tracked_objects::Location& from_here,
@@ -70,11 +70,11 @@ class CONTENT_EXPORT RasterWorkerPool : public base::TaskRunner,
scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunner();
protected:
- ~RasterWorkerPool() override;
+ ~CategorizedWorkerPool() override;
private:
- class RasterWorkerPoolSequencedTaskRunner;
- friend class RasterWorkerPoolSequencedTaskRunner;
+ class CategorizedWorkerPoolSequencedTaskRunner;
+ friend class CategorizedWorkerPoolSequencedTaskRunner;
// Simple Task for the TaskGraphRunner that wraps a closure.
// This class is used to schedule TaskRunner tasks on the
@@ -145,4 +145,4 @@ class CONTENT_EXPORT RasterWorkerPool : public base::TaskRunner,
} // namespace content
-#endif // CONTENT_RENDERER_RASTER_WORKER_POOL_H_
+#endif // CONTENT_RENDERER_CATEGORIZED_WORKER_POOL_H_
diff --git a/chromium/content/renderer/categorized_worker_pool_unittest.cc b/chromium/content/renderer/categorized_worker_pool_unittest.cc
new file mode 100644
index 00000000000..9e6fb19ec0a
--- /dev/null
+++ b/chromium/content/renderer/categorized_worker_pool_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/sequenced_task_runner_test_template.h"
+#include "base/test/task_runner_test_template.h"
+#include "base/threading/simple_thread.h"
+#include "cc/test/task_graph_runner_test_template.h"
+#include "content/renderer/categorized_worker_pool.h"
+
+namespace base {
+namespace {
+
+// Number of threads spawned in tests.
+const int kNumThreads = 4;
+
+class CategorizedWorkerPoolTestDelegate {
+ public:
+ CategorizedWorkerPoolTestDelegate()
+ : categorized_worker_pool_(new content::CategorizedWorkerPool()) {}
+
+ void StartTaskRunner() { categorized_worker_pool_->Start(kNumThreads); }
+
+ scoped_refptr<content::CategorizedWorkerPool> GetTaskRunner() {
+ return categorized_worker_pool_;
+ }
+
+ void StopTaskRunner() { categorized_worker_pool_->FlushForTesting(); }
+
+ ~CategorizedWorkerPoolTestDelegate() { categorized_worker_pool_->Shutdown(); }
+
+ private:
+ scoped_refptr<content::CategorizedWorkerPool> categorized_worker_pool_;
+};
+
+INSTANTIATE_TYPED_TEST_CASE_P(CategorizedWorkerPool,
+ TaskRunnerTest,
+ CategorizedWorkerPoolTestDelegate);
+
+class CategorizedWorkerPoolSequencedTestDelegate {
+ public:
+ CategorizedWorkerPoolSequencedTestDelegate()
+ : categorized_worker_pool_(new content::CategorizedWorkerPool()) {}
+
+ void StartTaskRunner() { categorized_worker_pool_->Start(kNumThreads); }
+
+ scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
+ return categorized_worker_pool_->CreateSequencedTaskRunner();
+ }
+
+ void StopTaskRunner() { categorized_worker_pool_->FlushForTesting(); }
+
+ ~CategorizedWorkerPoolSequencedTestDelegate() {
+ categorized_worker_pool_->Shutdown();
+ }
+
+ private:
+ scoped_refptr<content::CategorizedWorkerPool> categorized_worker_pool_;
+};
+
+INSTANTIATE_TYPED_TEST_CASE_P(CategorizedWorkerPool,
+ SequencedTaskRunnerTest,
+ CategorizedWorkerPoolSequencedTestDelegate);
+
+} // namespace
+} // namespace base
+
+namespace cc {
+namespace {
+
+template <int NumThreads>
+class CategorizedWorkerPoolTaskGraphRunnerTestDelegate {
+ public:
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate()
+ : categorized_worker_pool_(new content::CategorizedWorkerPool()) {}
+
+ void StartTaskGraphRunner() { categorized_worker_pool_->Start(NumThreads); }
+
+ cc::TaskGraphRunner* GetTaskGraphRunner() {
+ return categorized_worker_pool_->GetTaskGraphRunner();
+ }
+
+ void StopTaskGraphRunner() { categorized_worker_pool_->FlushForTesting(); }
+
+ ~CategorizedWorkerPoolTaskGraphRunnerTestDelegate() {
+ categorized_worker_pool_->Shutdown();
+ }
+
+ private:
+ scoped_refptr<content::CategorizedWorkerPool> categorized_worker_pool_;
+};
+
+// Multithreaded tests.
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool_1_Threads,
+ TaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<1>);
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool_2_Threads,
+ TaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<2>);
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool_3_Threads,
+ TaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<3>);
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool_4_Threads,
+ TaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<4>);
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool_5_Threads,
+ TaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<5>);
+
+// Single threaded tests.
+INSTANTIATE_TYPED_TEST_CASE_P(
+ CategorizedWorkerPool,
+ SingleThreadTaskGraphRunnerTest,
+ CategorizedWorkerPoolTaskGraphRunnerTestDelegate<1>);
+
+} // namespace
+} // namespace cc
diff --git a/chromium/content/renderer/child_frame_compositing_helper.cc b/chromium/content/renderer/child_frame_compositing_helper.cc
index cc2ba004c4d..9b98bc69ec1 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.cc
+++ b/chromium/content/renderer/child_frame_compositing_helper.cc
@@ -149,7 +149,7 @@ void ChildFrameCompositingHelper::ChildFrameGone() {
void ChildFrameCompositingHelper::SatisfyCallback(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
- cc::SurfaceSequence sequence) {
+ const cc::SurfaceSequence& sequence) {
// This may be called on either the main or impl thread.
sender->Send(new FrameHostMsg_SatisfySequence(host_routing_id, sequence));
}
@@ -159,7 +159,7 @@ void ChildFrameCompositingHelper::SatisfyCallbackBrowserPlugin(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
int browser_plugin_instance_id,
- cc::SurfaceSequence sequence) {
+ const cc::SurfaceSequence& sequence) {
sender->Send(new BrowserPluginHostMsg_SatisfySequence(
host_routing_id, browser_plugin_instance_id, sequence));
}
@@ -168,8 +168,8 @@ void ChildFrameCompositingHelper::SatisfyCallbackBrowserPlugin(
void ChildFrameCompositingHelper::RequireCallback(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
- cc::SurfaceId id,
- cc::SurfaceSequence sequence) {
+ const cc::SurfaceId& id,
+ const cc::SurfaceSequence& sequence) {
// This may be called on either the main or impl thread.
sender->Send(new FrameHostMsg_RequireSequence(host_routing_id, id, sequence));
}
@@ -178,8 +178,8 @@ void ChildFrameCompositingHelper::RequireCallbackBrowserPlugin(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
int browser_plugin_instance_id,
- cc::SurfaceId id,
- cc::SurfaceSequence sequence) {
+ const cc::SurfaceId& id,
+ const cc::SurfaceSequence& sequence) {
// This may be called on either the main or impl thread.
sender->Send(new BrowserPluginHostMsg_RequireSequence(
host_routing_id, browser_plugin_instance_id, id, sequence));
diff --git a/chromium/content/renderer/child_frame_compositing_helper.h b/chromium/content/renderer/child_frame_compositing_helper.h
index e51ab82870b..09548c71f92 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.h
+++ b/chromium/content/renderer/child_frame_compositing_helper.h
@@ -93,22 +93,22 @@ class CONTENT_EXPORT ChildFrameCompositingHelper
cc::Layer* layer);
static void SatisfyCallback(scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
- cc::SurfaceSequence sequence);
+ const cc::SurfaceSequence& sequence);
static void SatisfyCallbackBrowserPlugin(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
int browser_plugin_instance_id,
- cc::SurfaceSequence sequence);
+ const cc::SurfaceSequence& sequence);
static void RequireCallback(scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
- cc::SurfaceId id,
- cc::SurfaceSequence sequence);
+ const cc::SurfaceId& id,
+ const cc::SurfaceSequence& sequence);
static void RequireCallbackBrowserPlugin(
scoped_refptr<ThreadSafeSender> sender,
int host_routing_id,
int browser_plugin_instance_id,
- cc::SurfaceId id,
- cc::SurfaceSequence sequence);
+ const cc::SurfaceId& id,
+ const cc::SurfaceSequence& sequence);
void UpdateWebLayer(blink::WebLayer* layer);
int host_routing_id_;
diff --git a/chromium/content/renderer/devtools/devtools_agent.cc b/chromium/content/renderer/devtools/devtools_agent.cc
index 87820f63c32..858e75fd0b9 100644
--- a/chromium/content/renderer/devtools/devtools_agent.cc
+++ b/chromium/content/renderer/devtools/devtools_agent.cc
@@ -22,6 +22,7 @@
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
#include "ipc/ipc_channel.h"
+#include "third_party/WebKit/public/platform/WebFloatRect.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebDevToolsAgent.h"
@@ -107,6 +108,10 @@ void DevToolsAgent::WidgetWillClose() {
ContinueProgram();
}
+void DevToolsAgent::OnDestruct() {
+ delete this;
+}
+
void DevToolsAgent::sendProtocolMessage(int session_id,
int call_id,
const blink::WebString& message,
@@ -258,7 +263,9 @@ void DevToolsAgent::OnDispatchOnInspectorBackend(int session_id,
}
void DevToolsAgent::OnInspectElement(int x, int y) {
- GetWebAgent()->inspectElementAt(WebPoint(x, y));
+ blink::WebFloatRect point_rect(x, y, 0, 0);
+ frame_->GetRenderWidget()->convertWindowToViewport(&point_rect);
+ GetWebAgent()->inspectElementAt(WebPoint(point_rect.x, point_rect.y));
}
void DevToolsAgent::OnRequestNewWindowACK(bool success) {
diff --git a/chromium/content/renderer/devtools/devtools_agent.h b/chromium/content/renderer/devtools/devtools_agent.h
index 04a5ddec5be..f1a2ea4c315 100644
--- a/chromium/content/renderer/devtools/devtools_agent.h
+++ b/chromium/content/renderer/devtools/devtools_agent.h
@@ -58,6 +58,7 @@ class CONTENT_EXPORT DevToolsAgent
// RenderFrameObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
void WidgetWillClose() override;
+ void OnDestruct() override;
// WebDevToolsAgentClient implementation.
void sendProtocolMessage(int session_id,
diff --git a/chromium/content/renderer/devtools/devtools_agent_filter.cc b/chromium/content/renderer/devtools/devtools_agent_filter.cc
index 0ccf71b20a4..1e015f7910f 100644
--- a/chromium/content/renderer/devtools/devtools_agent_filter.cc
+++ b/chromium/content/renderer/devtools/devtools_agent_filter.cc
@@ -21,8 +21,12 @@ namespace {
class MessageImpl : public WebDevToolsAgent::MessageDescriptor {
public:
- MessageImpl(const std::string& message, int routing_id)
- : msg_(message),
+ MessageImpl(
+ const std::string& method,
+ const std::string& message,
+ int routing_id)
+ : method_(method),
+ msg_(message),
routing_id_(routing_id) {
}
~MessageImpl() override {}
@@ -33,8 +37,10 @@ class MessageImpl : public WebDevToolsAgent::MessageDescriptor {
return agent->GetWebAgent();
}
WebString message() override { return WebString::fromUTF8(msg_); }
+ WebString method() override { return WebString::fromUTF8(method_); }
private:
+ std::string method_;
std::string msg_;
int routing_id_;
};
@@ -72,7 +78,7 @@ void DevToolsAgentFilter::OnDispatchOnInspectorBackend(
if (WebDevToolsAgent::shouldInterruptForMethod(
WebString::fromUTF8(method))) {
WebDevToolsAgent::interruptAndDispatch(
- session_id, new MessageImpl(message, current_routing_id_));
+ session_id, new MessageImpl(method, message, current_routing_id_));
}
}
diff --git a/chromium/content/renderer/devtools/devtools_client.cc b/chromium/content/renderer/devtools/devtools_client.cc
index 3f961293824..edc31a3f368 100644
--- a/chromium/content/renderer/devtools/devtools_client.cc
+++ b/chromium/content/renderer/devtools/devtools_client.cc
@@ -39,6 +39,10 @@ void DevToolsClient::DidClearWindowObject() {
render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(compatibility_script_));
}
+void DevToolsClient::OnDestruct() {
+ delete this;
+}
+
void DevToolsClient::sendMessageToEmbedder(const WebString& message) {
Send(new DevToolsHostMsg_DispatchOnEmbedder(routing_id(),
message.utf8()));
diff --git a/chromium/content/renderer/devtools/devtools_client.h b/chromium/content/renderer/devtools/devtools_client.h
index 3d14c4a69c5..d4206e5a8a0 100644
--- a/chromium/content/renderer/devtools/devtools_client.h
+++ b/chromium/content/renderer/devtools/devtools_client.h
@@ -38,6 +38,7 @@ class CONTENT_EXPORT DevToolsClient
private:
// RenderFrameObserver overrides.
void DidClearWindowObject() override;
+ void OnDestruct() override;
// WebDevToolsFrontendClient implementation.
void sendMessageToEmbedder(const blink::WebString&) override;
diff --git a/chromium/content/renderer/devtools/render_widget_screen_metrics_emulator.cc b/chromium/content/renderer/devtools/render_widget_screen_metrics_emulator.cc
index bad6fa72699..d5f4983f139 100644
--- a/chromium/content/renderer/devtools/render_widget_screen_metrics_emulator.cc
+++ b/chromium/content/renderer/devtools/render_widget_screen_metrics_emulator.cc
@@ -25,10 +25,10 @@ RenderWidgetScreenMetricsEmulator::RenderWidgetScreenMetricsEmulator(
}
RenderWidgetScreenMetricsEmulator::~RenderWidgetScreenMetricsEmulator() {
+ delegate_->Resize(original_resize_params_);
delegate_->SetScreenMetricsEmulationParameters(false, emulation_params_);
delegate_->SetScreenRects(original_view_screen_rect_,
original_window_screen_rect_);
- delegate_->Resize(original_resize_params_);
}
void RenderWidgetScreenMetricsEmulator::ChangeEmulationParams(
diff --git a/chromium/content/renderer/devtools/v8_sampling_profiler.cc b/chromium/content/renderer/devtools/v8_sampling_profiler.cc
index 5aca412225c..baf2e50b372 100644
--- a/chromium/content/renderer/devtools/v8_sampling_profiler.cc
+++ b/chromium/content/renderer/devtools/v8_sampling_profiler.cc
@@ -639,7 +639,9 @@ void V8SamplingProfiler::EnableSamplingEventForTesting(int code_added_events,
int sample_events) {
render_thread_sampler_->SetEventsToCollectForTest(code_added_events,
sample_events);
- waitable_event_for_testing_.reset(new base::WaitableEvent(false, false));
+ waitable_event_for_testing_.reset(
+ new base::WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED));
}
void V8SamplingProfiler::WaitSamplingEventForTesting() {
diff --git a/chromium/content/renderer/devtools/v8_sampling_profiler_browsertest.cc b/chromium/content/renderer/devtools/v8_sampling_profiler_browsertest.cc
index af31cde91c3..eb1f2af080f 100644
--- a/chromium/content/renderer/devtools/v8_sampling_profiler_browsertest.cc
+++ b/chromium/content/renderer/devtools/v8_sampling_profiler_browsertest.cc
@@ -2,15 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/renderer/devtools/v8_sampling_profiler.h"
+
#include <stddef.h>
+#include <utility>
+
#include "base/json/json_reader.h"
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
#include "base/trace_event/trace_buffer.h"
#include "base/trace_event/trace_event.h"
#include "content/public/test/render_view_test.h"
-#include "content/renderer/devtools/v8_sampling_profiler.h"
using base::DictionaryValue;
using base::ListValue;
@@ -37,7 +40,9 @@ class V8SamplingProfilerTest : public RenderViewTest {
void KickV8() { ExecuteJavaScriptForTests("1"); }
void SyncFlush(TraceLog* trace_log) {
- base::WaitableEvent flush_complete_event(false, false);
+ base::WaitableEvent flush_complete_event(
+ base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
trace_log->Flush(
base::Bind(&V8SamplingProfilerTest::OnTraceDataCollected,
base::Unretained(static_cast<V8SamplingProfilerTest*>(this)),
@@ -73,7 +78,7 @@ class V8SamplingProfilerTest : public RenderViewTest {
while (root_list->GetSize()) {
std::unique_ptr<Value> item;
root_list->Remove(0, &item);
- trace_parsed_.Append(item.release());
+ trace_parsed_.Append(std::move(item));
}
if (!has_more_events)
diff --git a/chromium/content/renderer/dom_automation_controller.cc b/chromium/content/renderer/dom_automation_controller.cc
index 3f119b6920d..91b456a3832 100644
--- a/chromium/content/renderer/dom_automation_controller.cc
+++ b/chromium/content/renderer/dom_automation_controller.cc
@@ -102,8 +102,8 @@ bool DomAutomationController::SendMsg(const gin::Arguments& args) {
(args.PeekNext()->IsString() || args.PeekNext()->IsBoolean() ||
args.PeekNext()->IsNumber())) {
V8ValueConverterImpl conv;
- value.reset(
- conv.FromV8Value(args.PeekNext(), args.isolate()->GetCurrentContext()));
+ value =
+ conv.FromV8Value(args.PeekNext(), args.isolate()->GetCurrentContext());
} else {
return false;
}
diff --git a/chromium/content/renderer/dom_serializer_browsertest.cc b/chromium/content/renderer/dom_serializer_browsertest.cc
index 3c3e549c12b..d475fe2e0da 100644
--- a/chromium/content/renderer/dom_serializer_browsertest.cc
+++ b/chromium/content/renderer/dom_serializer_browsertest.cc
@@ -75,6 +75,9 @@ class LoadObserver : public RenderViewObserver {
}
private:
+ // RenderViewObserver implementation.
+ void OnDestruct() override { delete this; }
+
base::Closure quit_closure_;
};
diff --git a/chromium/content/renderer/external_popup_menu.cc b/chromium/content/renderer/external_popup_menu.cc
index 7bb01a1d320..95b41a757e6 100644
--- a/chromium/content/renderer/external_popup_menu.cc
+++ b/chromium/content/renderer/external_popup_menu.cc
@@ -63,6 +63,7 @@ void ExternalPopupMenu::close() {
// |this| was deleted.
}
+#if defined(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
void ExternalPopupMenu::DidSelectItem(int index) {
if (!popup_menu_client_)
@@ -72,9 +73,7 @@ void ExternalPopupMenu::DidSelectItem(int index) {
else
popup_menu_client_->didAcceptIndex(index);
}
-#endif
-
-#if defined(OS_ANDROID)
+#else
void ExternalPopupMenu::DidSelectItems(bool canceled,
const std::vector<int>& indices) {
if (!popup_menu_client_)
@@ -85,5 +84,6 @@ void ExternalPopupMenu::DidSelectItems(bool canceled,
popup_menu_client_->didAcceptIndices(indices);
}
#endif
+#endif
} // namespace content
diff --git a/chromium/content/renderer/external_popup_menu.h b/chromium/content/renderer/external_popup_menu.h
index 0d99eb7e6d9..0158f99fc0d 100644
--- a/chromium/content/renderer/external_popup_menu.h
+++ b/chromium/content/renderer/external_popup_menu.h
@@ -31,16 +31,16 @@ class ExternalPopupMenu : public blink::WebExternalPopupMenu {
void SetOriginScaleAndOffsetForEmulation(
float scale, const gfx::PointF& offset);
+#if defined(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
// Called when the user has selected an item. |selected_item| is -1 if the
// user canceled the popup.
void DidSelectItem(int selected_index);
-#endif
-
-#if defined(OS_ANDROID)
+#else
// Called when the user has selected items or canceled the popup.
void DidSelectItems(bool canceled, const std::vector<int>& selected_indices);
#endif
+#endif
// blink::WebExternalPopupMenu implementation:
void show(const blink::WebRect& bounds) override;
diff --git a/chromium/content/renderer/external_popup_menu_browsertest.cc b/chromium/content/renderer/external_popup_menu_browsertest.cc
index ea6054b92d3..d1eb5a4520d 100644
--- a/chromium/content/renderer/external_popup_menu_browsertest.cc
+++ b/chromium/content/renderer/external_popup_menu_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/frame_messages.h"
@@ -87,10 +89,10 @@ TEST_F(ExternalPopupMenuTest, NormalCase) {
const IPC::Message* message =
sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
ASSERT_TRUE(message != NULL);
- base::Tuple<FrameHostMsg_ShowPopup_Params> param;
+ std::tuple<FrameHostMsg_ShowPopup_Params> param;
FrameHostMsg_ShowPopup::Read(message, &param);
- ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
- EXPECT_EQ(1, base::get<0>(param).selected_item);
+ ASSERT_EQ(3U, std::get<0>(param).popup_items.size());
+ EXPECT_EQ(1, std::get<0>(param).selected_item);
// Simulate the user canceling the popup; the index should not have changed.
frame()->OnSelectPopupMenuItem(-1);
@@ -107,8 +109,8 @@ TEST_F(ExternalPopupMenuTest, NormalCase) {
message = sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
ASSERT_TRUE(message != NULL);
FrameHostMsg_ShowPopup::Read(message, &param);
- ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
- EXPECT_EQ(0, base::get<0>(param).selected_item);
+ ASSERT_EQ(3U, std::get<0>(param).popup_items.size());
+ EXPECT_EQ(0, std::get<0>(param).selected_item);
}
// Page shows popup, then navigates away while popup showing, then select.
@@ -190,11 +192,11 @@ TEST_F(ExternalPopupMenuDisplayNoneTest, SelectItem) {
const IPC::Message* message =
sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
ASSERT_TRUE(message != NULL);
- base::Tuple<FrameHostMsg_ShowPopup_Params> param;
+ std::tuple<FrameHostMsg_ShowPopup_Params> param;
FrameHostMsg_ShowPopup::Read(message, &param);
// Number of items should match item count minus the number
// of "display: none" items.
- ASSERT_EQ(5U, base::get<0>(param).popup_items.size());
+ ASSERT_EQ(5U, std::get<0>(param).popup_items.size());
// Select index 1 item. This should select item with index 2,
// skipping the item with 'display: none'
diff --git a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
index d97dbe23377..1eea2aafb99 100644
--- a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
+++ b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
@@ -44,7 +44,7 @@ MultiResolutionImageResourceFetcher::MultiResolutionImageResourceFetcher(
// workers. This should ideally not happen or at least not all the time.
// See https://crbug.com/448427
if (request_context == WebURLRequest::RequestContextFavicon)
- fetcher_->SetSkipServiceWorker(true);
+ fetcher_->SetSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);
fetcher_->SetCachePolicy(cache_policy);
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
index fa58f999c84..51878491e6a 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -69,7 +69,8 @@ void ResourceFetcherImpl::SetHeader(const std::string& header,
}
}
-void ResourceFetcherImpl::SetSkipServiceWorker(bool skip_service_worker) {
+void ResourceFetcherImpl::SetSkipServiceWorker(
+ blink::WebURLRequest::SkipServiceWorker skip_service_worker) {
DCHECK(!request_.isNull());
DCHECK(!loader_);
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.h b/chromium/content/renderer/fetchers/resource_fetcher_impl.h
index 38f3bb39940..731ca48832c 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.h
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.h
@@ -35,7 +35,8 @@ class ResourceFetcherImpl : public ResourceFetcher,
void SetMethod(const std::string& method) override;
void SetBody(const std::string& body) override;
void SetHeader(const std::string& header, const std::string& value) override;
- void SetSkipServiceWorker(bool skip_service_worker) override;
+ void SetSkipServiceWorker(
+ blink::WebURLRequest::SkipServiceWorker skip_service_worker) override;
void SetCachePolicy(blink::WebCachePolicy policy) override;
void SetLoaderOptions(const blink::WebURLLoaderOptions& options) override;
void Start(blink::WebFrame* frame,
diff --git a/chromium/content/renderer/frame_blame_context.cc b/chromium/content/renderer/frame_blame_context.cc
index 74ed6ee2b25..a73f347cb4d 100644
--- a/chromium/content/renderer/frame_blame_context.cc
+++ b/chromium/content/renderer/frame_blame_context.cc
@@ -24,7 +24,7 @@ base::trace_event::BlameContext* GetParentBlameContext(
const char kFrameBlameContextCategory[] = "blink";
const char kFrameBlameContextName[] = "FrameBlameContext";
-const char kFrameBlameContextType[] = "Frame";
+const char kFrameBlameContextType[] = "RenderFrame";
const char kFrameBlameContextScope[] = "RenderFrame";
FrameBlameContext::FrameBlameContext(RenderFrameImpl* render_frame,
diff --git a/chromium/content/renderer/gamepad_shared_memory_reader.cc b/chromium/content/renderer/gamepad_shared_memory_reader.cc
index 89ed79eb1fd..f561e5dee84 100644
--- a/chromium/content/renderer/gamepad_shared_memory_reader.cc
+++ b/chromium/content/renderer/gamepad_shared_memory_reader.cc
@@ -7,7 +7,6 @@
#include "base/metrics/histogram.h"
#include "base/trace_event/trace_event.h"
#include "content/common/gamepad_hardware_buffer.h"
-#include "content/common/gamepad_user_gesture.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "ipc/ipc_sync_message_filter.h"
diff --git a/chromium/content/renderer/gpu/compositor_dependencies.h b/chromium/content/renderer/gpu/compositor_dependencies.h
index cee05271378..9a886ddf948 100644
--- a/chromium/content/renderer/gpu/compositor_dependencies.h
+++ b/chromium/content/renderer/gpu/compositor_dependencies.h
@@ -54,6 +54,8 @@ class CompositorDependencies {
virtual cc::SharedBitmapManager* GetSharedBitmapManager() = 0;
virtual gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() = 0;
virtual scheduler::RendererScheduler* GetRendererScheduler() = 0;
+ // TODO(danakj): This should be part of RenderThreadImpl (or some API from it
+ // to RenderWidget). But RenderThreadImpl is null in RenderViewTest.
virtual std::unique_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
int routing_id) = 0;
virtual cc::ImageSerializationProcessor* GetImageSerializationProcessor() = 0;
diff --git a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
index aa4a456ac29..e2d13608ac7 100644
--- a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
+++ b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.cc
@@ -32,19 +32,19 @@ CompositorExternalBeginFrameSource::~CompositorExternalBeginFrameSource() {
}
}
-void CompositorExternalBeginFrameSource::OnNeedsBeginFramesChanged(
- bool needs_begin_frames) {
- DCHECK(CalledOnValidThread());
- if (!needs_begin_frames)
- missed_begin_frame_args_ = cc::BeginFrameArgs();
- Send(new ViewHostMsg_SetNeedsBeginFrames(routing_id_, needs_begin_frames));
-}
-
void CompositorExternalBeginFrameSource::AddObserver(
cc::BeginFrameObserver* obs) {
DCHECK(CalledOnValidThread());
+ DCHECK(obs);
+ DCHECK(observers_.find(obs) == observers_.end());
+
SetClientReady();
- BeginFrameSourceBase::AddObserver(obs);
+ bool observers_was_empty = observers_.empty();
+ observers_.insert(obs);
+ obs->OnBeginFrameSourcePausedChanged(paused_);
+ if (observers_was_empty)
+ Send(new ViewHostMsg_SetNeedsBeginFrames(routing_id_, true));
+
// Send a MISSED begin frame if necessary.
if (missed_begin_frame_args_.IsValid()) {
cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
@@ -55,6 +55,18 @@ void CompositorExternalBeginFrameSource::AddObserver(
}
}
+void CompositorExternalBeginFrameSource::RemoveObserver(
+ cc::BeginFrameObserver* obs) {
+ DCHECK(obs);
+ DCHECK(observers_.find(obs) != observers_.end());
+
+ observers_.erase(obs);
+ if (observers_.empty()) {
+ missed_begin_frame_args_ = cc::BeginFrameArgs();
+ Send(new ViewHostMsg_SetNeedsBeginFrames(routing_id_, false));
+ }
+}
+
void CompositorExternalBeginFrameSource::SetClientReady() {
DCHECK(CalledOnValidThread());
if (begin_frame_source_proxy_)
@@ -74,16 +86,30 @@ void CompositorExternalBeginFrameSource::OnMessageReceived(
DCHECK(CalledOnValidThread());
DCHECK(begin_frame_source_proxy_.get());
IPC_BEGIN_MESSAGE_MAP(CompositorExternalBeginFrameSource, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetBeginFramePaused,
+ OnSetBeginFrameSourcePaused)
IPC_MESSAGE_HANDLER(ViewMsg_BeginFrame, OnBeginFrame)
IPC_END_MESSAGE_MAP()
}
+void CompositorExternalBeginFrameSource::OnSetBeginFrameSourcePaused(
+ bool paused) {
+ if (paused_ == paused)
+ return;
+ paused_ = paused;
+ std::unordered_set<cc::BeginFrameObserver*> observers(observers_);
+ for (auto* obs : observers)
+ obs->OnBeginFrameSourcePausedChanged(paused_);
+}
+
void CompositorExternalBeginFrameSource::OnBeginFrame(
const cc::BeginFrameArgs& args) {
DCHECK(CalledOnValidThread());
missed_begin_frame_args_ = args;
missed_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
- CallOnBeginFrame(args);
+ std::unordered_set<cc::BeginFrameObserver*> observers(observers_);
+ for (auto* obs : observers)
+ obs->OnBeginFrame(args);
}
bool CompositorExternalBeginFrameSource::Send(IPC::Message* message) {
diff --git a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.h b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.h
index 116529a229f..8a965772f36 100644
--- a/chromium/content/renderer/gpu/compositor_external_begin_frame_source.h
+++ b/chromium/content/renderer/gpu/compositor_external_begin_frame_source.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_RENDERER_GPU_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
#define CONTENT_RENDERER_GPU_COMPOSITOR_EXTERNAL_BEGIN_FRAME_SOURCE_H_
+#include <unordered_set>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -21,7 +23,7 @@ namespace content {
// This class can be created only on the main thread, but then becomes pinned
// to a fixed thread where cc::Scheduler is running.
class CompositorExternalBeginFrameSource
- : public cc::BeginFrameSourceBase,
+ : public cc::BeginFrameSource,
public NON_EXPORTED_BASE(base::NonThreadSafe) {
public:
explicit CompositorExternalBeginFrameSource(
@@ -30,9 +32,11 @@ class CompositorExternalBeginFrameSource
int routing_id);
~CompositorExternalBeginFrameSource() override;
- // cc::BeginFrameSourceBase implementation.
+ // cc::BeginFrameSource implementation.
void AddObserver(cc::BeginFrameObserver* obs) override;
- void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
+ void RemoveObserver(cc::BeginFrameObserver* obs) override;
+ void DidFinishFrame(cc::BeginFrameObserver* obs,
+ size_t remaining_frames) override {}
private:
class CompositorExternalBeginFrameSourceProxy
@@ -61,6 +65,7 @@ class CompositorExternalBeginFrameSource
void SetClientReady();
void OnMessageReceived(const IPC::Message& message);
+ void OnSetBeginFrameSourcePaused(bool paused);
void OnBeginFrame(const cc::BeginFrameArgs& args);
bool Send(IPC::Message* message);
@@ -71,6 +76,8 @@ class CompositorExternalBeginFrameSource
int routing_id_;
CompositorForwardingMessageFilter::Handler begin_frame_source_filter_handler_;
cc::BeginFrameArgs missed_begin_frame_args_;
+ std::unordered_set<cc::BeginFrameObserver*> observers_;
+ bool paused_ = false;
DISALLOW_COPY_AND_ASSIGN(CompositorExternalBeginFrameSource);
};
diff --git a/chromium/content/renderer/gpu/compositor_forwarding_message_filter.cc b/chromium/content/renderer/gpu/compositor_forwarding_message_filter.cc
index ff657dc58f6..4914fd3fe63 100644
--- a/chromium/content/renderer/gpu/compositor_forwarding_message_filter.cc
+++ b/chromium/content/renderer/gpu/compositor_forwarding_message_filter.cc
@@ -47,6 +47,7 @@ void CompositorForwardingMessageFilter::RemoveHandlerOnCompositorThread(
bool CompositorForwardingMessageFilter::OnMessageReceived(
const IPC::Message& message) {
switch(message.type()) {
+ case ViewMsg_SetBeginFramePaused::ID: // Fall through.
case ViewMsg_BeginFrame::ID: // Fall through.
case ViewMsg_ReclaimCompositorResources::ID: // Fall through.
case ViewMsg_SwapCompositorFrameAck::ID: // Fall through.
diff --git a/chromium/content/renderer/gpu/compositor_output_surface.cc b/chromium/content/renderer/gpu/compositor_output_surface.cc
index 1284fe47d65..a240b19736e 100644
--- a/chromium/content/renderer/gpu/compositor_output_surface.cc
+++ b/chromium/content/renderer/gpu/compositor_output_surface.cc
@@ -30,31 +30,43 @@ namespace content {
CompositorOutputSurface::CompositorOutputSurface(
int32_t routing_id,
uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>& worker_context_provider,
- const scoped_refptr<cc::VulkanContextProvider>& vulkan_context_provider,
- std::unique_ptr<cc::SoftwareOutputDevice> software_device,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue,
- bool use_swap_compositor_frame_message)
- : OutputSurface(context_provider,
- worker_context_provider,
- vulkan_context_provider,
- std::move(software_device)),
+ scoped_refptr<cc::ContextProvider> context_provider,
+ scoped_refptr<cc::ContextProvider> worker_context_provider,
+ scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue)
+ : OutputSurface(std::move(context_provider),
+ std::move(worker_context_provider),
+ nullptr),
output_surface_id_(output_surface_id),
- use_swap_compositor_frame_message_(use_swap_compositor_frame_message),
output_surface_filter_(
RenderThreadImpl::current()->compositor_message_filter()),
+ message_sender_(RenderThreadImpl::current()->sync_message_filter()),
frame_swap_message_queue_(swap_frame_message_queue),
- routing_id_(routing_id),
- layout_test_mode_(RenderThreadImpl::current()->layout_test_mode()),
- weak_ptrs_(this) {
- DCHECK(output_surface_filter_.get());
- DCHECK(frame_swap_message_queue_.get());
- message_sender_ = RenderThreadImpl::current()->sync_message_filter();
- DCHECK(message_sender_.get());
+ routing_id_(routing_id) {
+ DCHECK(output_surface_filter_);
+ DCHECK(frame_swap_message_queue_);
+ DCHECK(message_sender_);
+ capabilities_.delegated_rendering = true;
}
-CompositorOutputSurface::~CompositorOutputSurface() {}
+CompositorOutputSurface::CompositorOutputSurface(
+ int32_t routing_id,
+ uint32_t output_surface_id,
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider,
+ scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue)
+ : OutputSurface(std::move(vulkan_context_provider)),
+ output_surface_id_(output_surface_id),
+ output_surface_filter_(
+ RenderThreadImpl::current()->compositor_message_filter()),
+ message_sender_(RenderThreadImpl::current()->sync_message_filter()),
+ frame_swap_message_queue_(swap_frame_message_queue),
+ routing_id_(routing_id) {
+ DCHECK(output_surface_filter_);
+ DCHECK(frame_swap_message_queue_);
+ DCHECK(message_sender_);
+ capabilities_.delegated_rendering = true;
+}
+
+CompositorOutputSurface::~CompositorOutputSurface() = default;
bool CompositorOutputSurface::BindToClient(
cc::OutputSurfaceClient* client) {
@@ -91,70 +103,33 @@ void CompositorOutputSurface::DetachFromClient() {
cc::OutputSurface::DetachFromClient();
}
-void CompositorOutputSurface::ShortcutSwapAck(
- uint32_t output_surface_id,
- std::unique_ptr<cc::GLFrameData> gl_frame_data) {
- if (!layout_test_previous_frame_ack_) {
- layout_test_previous_frame_ack_.reset(new cc::CompositorFrameAck);
- layout_test_previous_frame_ack_->gl_frame_data.reset(new cc::GLFrameData);
+void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame frame) {
+ {
+ std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
+ send_message_scope =
+ frame_swap_message_queue_->AcquireSendMessageScope();
+ std::vector<std::unique_ptr<IPC::Message>> messages;
+ std::vector<IPC::Message> messages_to_deliver_with_frame;
+ frame_swap_message_queue_->DrainMessages(&messages);
+ FrameSwapMessageQueue::TransferMessages(&messages,
+ &messages_to_deliver_with_frame);
+ Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, output_surface_id_,
+ frame,
+ messages_to_deliver_with_frame));
+ // ~send_message_scope.
}
+ client_->DidSwapBuffers();
+}
- OnSwapAck(output_surface_id, *layout_test_previous_frame_ack_);
-
- layout_test_previous_frame_ack_->gl_frame_data = std::move(gl_frame_data);
+void CompositorOutputSurface::BindFramebuffer() {
+ // This is a delegating output surface, no framebuffer/direct drawing support.
+ NOTREACHED();
}
-void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
- DCHECK(use_swap_compositor_frame_message_);
- if (layout_test_mode_) {
- // This code path is here to support layout tests that are currently
- // doing a readback in the renderer instead of the browser. So they
- // are using deprecated code paths in the renderer and don't need to
- // actually swap anything to the browser. We shortcut the swap to the
- // browser here and just ack directly within the renderer process.
- // Once crbug.com/311404 is fixed, this can be removed.
-
- // This would indicate that crbug.com/311404 is being fixed, and this
- // block needs to be removed.
- DCHECK(!frame->delegated_frame_data);
-
- base::Closure closure = base::Bind(
- &CompositorOutputSurface::ShortcutSwapAck, weak_ptrs_.GetWeakPtr(),
- output_surface_id_, base::Passed(&frame->gl_frame_data));
-
- if (context_provider()) {
- gpu::gles2::GLES2Interface* context = context_provider()->ContextGL();
- const uint64_t fence_sync = context->InsertFenceSyncCHROMIUM();
- context->Flush();
-
- gpu::SyncToken sync_token;
- context->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
-
- context_provider()->ContextSupport()->SignalSyncToken(sync_token,
- closure);
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
- }
- client_->DidSwapBuffers();
- return;
- } else {
- {
- std::vector<std::unique_ptr<IPC::Message>> messages;
- std::vector<IPC::Message> messages_to_deliver_with_frame;
- std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
- send_message_scope =
- frame_swap_message_queue_->AcquireSendMessageScope();
- frame_swap_message_queue_->DrainMessages(&messages);
- FrameSwapMessageQueue::TransferMessages(&messages,
- &messages_to_deliver_with_frame);
- Send(new ViewHostMsg_SwapCompositorFrame(routing_id_,
- output_surface_id_,
- *frame,
- messages_to_deliver_with_frame));
- // ~send_message_scope.
- }
- client_->DidSwapBuffers();
- }
+uint32_t CompositorOutputSurface::GetFramebufferCopyTextureFormat() {
+ // This is a delegating output surface, no framebuffer/direct drawing support.
+ NOTREACHED();
+ return 0;
}
void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) {
diff --git a/chromium/content/renderer/gpu/compositor_output_surface.h b/chromium/content/renderer/gpu/compositor_output_surface.h
index fc311698e98..d3e78b21400 100644
--- a/chromium/content/renderer/gpu/compositor_output_surface.h
+++ b/chromium/content/renderer/gpu/compositor_output_surface.h
@@ -29,15 +29,14 @@ class Message;
namespace cc {
class CompositorFrame;
class CompositorFrameAck;
-class GLFrameData;
+class ContextProvider;
}
namespace content {
-class ContextProviderCommandBuffer;
class FrameSwapMessageQueue;
// This class can be created only on the main thread, but then becomes pinned
-// to a fixed thread when bindToClient is called.
+// to a fixed thread when BindToClient is called.
class CompositorOutputSurface
: NON_EXPORTED_BASE(public cc::OutputSurface),
NON_EXPORTED_BASE(public base::NonThreadSafe) {
@@ -45,27 +44,24 @@ class CompositorOutputSurface
CompositorOutputSurface(
int32_t routing_id,
uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>&
- worker_context_provider,
- const scoped_refptr<cc::VulkanContextProvider>& vulkan_context_provider,
- std::unique_ptr<cc::SoftwareOutputDevice> software,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue,
- bool use_swap_compositor_frame_message);
+ scoped_refptr<cc::ContextProvider> context_provider,
+ scoped_refptr<cc::ContextProvider> worker_context_provider,
+ scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue);
+ CompositorOutputSurface(
+ int32_t routing_id,
+ uint32_t output_surface_id,
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider,
+ scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue);
~CompositorOutputSurface() override;
// cc::OutputSurface implementation.
bool BindToClient(cc::OutputSurfaceClient* client) override;
void DetachFromClient() override;
- void SwapBuffers(cc::CompositorFrame* frame) override;
+ void SwapBuffers(cc::CompositorFrame frame) override;
+ void BindFramebuffer() override;
+ uint32_t GetFramebufferCopyTextureFormat() override;
protected:
- void ShortcutSwapAck(uint32_t output_surface_id,
- std::unique_ptr<cc::GLFrameData> gl_frame_data);
- virtual void OnSwapAck(uint32_t output_surface_id,
- const cc::CompositorFrameAck& ack);
- virtual void OnReclaimResources(uint32_t output_surface_id,
- const cc::CompositorFrameAck& ack);
uint32_t output_surface_id_;
private:
@@ -92,21 +88,17 @@ class CompositorOutputSurface
void OnMessageReceived(const IPC::Message& message);
void OnUpdateVSyncParametersFromBrowser(base::TimeTicks timebase,
base::TimeDelta interval);
+ void OnSwapAck(uint32_t output_surface_id, const cc::CompositorFrameAck& ack);
+ void OnReclaimResources(uint32_t output_surface_id,
+ const cc::CompositorFrameAck& ack);
bool Send(IPC::Message* message);
- bool use_swap_compositor_frame_message_;
-
scoped_refptr<CompositorForwardingMessageFilter> output_surface_filter_;
CompositorForwardingMessageFilter::Handler output_surface_filter_handler_;
scoped_refptr<CompositorOutputSurfaceProxy> output_surface_proxy_;
scoped_refptr<IPC::SyncMessageFilter> message_sender_;
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
int routing_id_;
-
- // TODO(danakj): Remove this when crbug.com/311404
- bool layout_test_mode_;
- std::unique_ptr<cc::CompositorFrameAck> layout_test_previous_frame_ack_;
- base::WeakPtrFactory<CompositorOutputSurface> weak_ptrs_;
};
} // namespace content
diff --git a/chromium/content/renderer/gpu/delegated_compositor_output_surface.cc b/chromium/content/renderer/gpu/delegated_compositor_output_surface.cc
deleted file mode 100644
index 97d838ead7e..00000000000
--- a/chromium/content/renderer/gpu/delegated_compositor_output_surface.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/gpu/delegated_compositor_output_surface.h"
-#include "content/renderer/gpu/frame_swap_message_queue.h"
-
-namespace content {
-
-DelegatedCompositorOutputSurface::DelegatedCompositorOutputSurface(
- int32_t routing_id,
- uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>& worker_context_provider,
- const scoped_refptr<cc::VulkanContextProvider>& vulkan_context_provider,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue)
- : CompositorOutputSurface(routing_id,
- output_surface_id,
- context_provider,
- worker_context_provider,
- vulkan_context_provider,
- std::unique_ptr<cc::SoftwareOutputDevice>(),
- swap_frame_message_queue,
- true) {
- capabilities_.delegated_rendering = true;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/gpu/delegated_compositor_output_surface.h b/chromium/content/renderer/gpu/delegated_compositor_output_surface.h
deleted file mode 100644
index aca19155b8d..00000000000
--- a/chromium/content/renderer/gpu/delegated_compositor_output_surface.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_
-#define CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_
-
-#include <stdint.h>
-
-#include "base/memory/ref_counted.h"
-#include "content/renderer/gpu/compositor_output_surface.h"
-
-namespace content {
-class FrameSwapMessageQueue;
-
-class DelegatedCompositorOutputSurface : public CompositorOutputSurface {
- public:
- DelegatedCompositorOutputSurface(
- int32_t routing_id,
- uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>&
- worker_context_provider,
- const scoped_refptr<cc::VulkanContextProvider>& vulkan_context_provider,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue);
- ~DelegatedCompositorOutputSurface() override {}
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_GPU_DELEGATED_COMPOSITOR_OUTPUT_SURFACE_H_
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
index 8fe5bae7d48..42f6995ff23 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -910,7 +910,7 @@ int GpuBenchmarking::RunMicroBenchmark(gin::Arguments* args) {
base::WrapUnique(V8ValueConverter::create());
v8::Local<v8::Context> v8_context = callback_and_context->GetContext();
std::unique_ptr<base::Value> value =
- base::WrapUnique(converter->FromV8Value(arguments, v8_context));
+ converter->FromV8Value(arguments, v8_context);
return context.compositor()->ScheduleMicroBenchmark(
name, std::move(value),
@@ -930,7 +930,7 @@ bool GpuBenchmarking::SendMessageToMicroBenchmark(
v8::Local<v8::Context> v8_context =
context.web_frame()->mainWorldScriptContext();
std::unique_ptr<base::Value> value =
- base::WrapUnique(converter->FromV8Value(message, v8_context));
+ converter->FromV8Value(message, v8_context);
return context.compositor()->SendMessageToMicroBenchmark(id,
std::move(value));
diff --git a/chromium/content/renderer/gpu/mailbox_output_surface.cc b/chromium/content/renderer/gpu/mailbox_output_surface.cc
deleted file mode 100644
index 4d90944759b..00000000000
--- a/chromium/content/renderer/gpu/mailbox_output_surface.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/gpu/mailbox_output_surface.h"
-
-#include "base/logging.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/output/gl_frame_data.h"
-#include "cc/resources/resource_provider.h"
-#include "content/renderer/gpu/frame_swap_message_queue.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-
-using cc::CompositorFrame;
-using cc::GLFrameData;
-using cc::ResourceProvider;
-using gpu::Mailbox;
-using gpu::gles2::GLES2Interface;
-
-namespace content {
-
-MailboxOutputSurface::MailboxOutputSurface(
- int32_t routing_id,
- uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>& worker_context_provider,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue,
- cc::ResourceFormat format)
- : CompositorOutputSurface(routing_id,
- output_surface_id,
- context_provider,
- worker_context_provider,
- nullptr,
- nullptr,
- swap_frame_message_queue,
- true),
- fbo_(0),
- is_backbuffer_discarded_(false),
- format_(format) {
- pending_textures_.push_back(TransferableFrame());
- capabilities_.uses_default_gl_framebuffer = false;
-}
-
-MailboxOutputSurface::~MailboxOutputSurface() {}
-
-void MailboxOutputSurface::DetachFromClient() {
- DiscardBackbuffer();
- while (!pending_textures_.empty()) {
- if (pending_textures_.front().texture_id) {
- context_provider_->ContextGL()->DeleteTextures(
- 1, &pending_textures_.front().texture_id);
- }
- pending_textures_.pop_front();
- }
- cc::OutputSurface::DetachFromClient();
-}
-
-void MailboxOutputSurface::EnsureBackbuffer() {
- is_backbuffer_discarded_ = false;
-
- GLES2Interface* gl = context_provider_->ContextGL();
-
- if (!current_backing_.texture_id) {
- // Find a texture of matching size to recycle.
- while (!returned_textures_.empty()) {
- TransferableFrame& texture = returned_textures_.front();
- if (texture.size == surface_size_) {
- current_backing_ = texture;
- if (current_backing_.sync_token.HasData())
- gl->WaitSyncTokenCHROMIUM(current_backing_.sync_token.GetConstData());
- returned_textures_.pop();
- break;
- }
-
- gl->DeleteTextures(1, &texture.texture_id);
- returned_textures_.pop();
- }
-
- if (!current_backing_.texture_id) {
- gl->GenTextures(1, &current_backing_.texture_id);
- current_backing_.size = surface_size_;
- gl->BindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->TexImage2D(GL_TEXTURE_2D,
- 0,
- GLInternalFormat(format_),
- surface_size_.width(),
- surface_size_.height(),
- 0,
- GLDataFormat(format_),
- GLDataType(format_),
- NULL);
- gl->GenMailboxCHROMIUM(current_backing_.mailbox.name);
- gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, current_backing_.mailbox.name);
- }
- }
-}
-
-void MailboxOutputSurface::DiscardBackbuffer() {
- is_backbuffer_discarded_ = true;
-
- GLES2Interface* gl = context_provider_->ContextGL();
-
- if (current_backing_.texture_id) {
- gl->DeleteTextures(1, &current_backing_.texture_id);
- current_backing_ = TransferableFrame();
- }
-
- while (!returned_textures_.empty()) {
- const TransferableFrame& frame = returned_textures_.front();
- gl->DeleteTextures(1, &frame.texture_id);
- returned_textures_.pop();
- }
-
- if (fbo_) {
- gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
- gl->DeleteFramebuffers(1, &fbo_);
- fbo_ = 0;
- }
-}
-
-void MailboxOutputSurface::Reshape(const gfx::Size& size,
- float scale_factor,
- bool alpha) {
- if (size == surface_size_)
- return;
-
- surface_size_ = size;
- device_scale_factor_ = scale_factor;
- DiscardBackbuffer();
- EnsureBackbuffer();
-}
-
-void MailboxOutputSurface::BindFramebuffer() {
- EnsureBackbuffer();
- DCHECK(current_backing_.texture_id);
-
- GLES2Interface* gl = context_provider_->ContextGL();
-
- if (!fbo_)
- gl->GenFramebuffers(1, &fbo_);
- gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
- gl->FramebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- current_backing_.texture_id,
- 0);
-}
-
-void MailboxOutputSurface::OnSwapAck(uint32_t output_surface_id,
- const cc::CompositorFrameAck& ack) {
- // Ignore message if it's a stale one coming from a different output surface
- // (e.g. after a lost context).
- if (output_surface_id != output_surface_id_) {
- CompositorOutputSurface::OnSwapAck(output_surface_id, ack);
- return;
- }
- if (!ack.gl_frame_data->mailbox.IsZero()) {
- DCHECK(!ack.gl_frame_data->size.IsEmpty());
- // The browser could be returning the oldest or any other pending texture
- // if it decided to skip a frame.
- std::deque<TransferableFrame>::iterator it;
- for (it = pending_textures_.begin(); it != pending_textures_.end(); it++) {
- DCHECK(!it->mailbox.IsZero());
- if (!memcmp(it->mailbox.name,
- ack.gl_frame_data->mailbox.name,
- sizeof(it->mailbox.name))) {
- DCHECK(it->size == ack.gl_frame_data->size);
- break;
- }
- }
- DCHECK(it != pending_textures_.end());
- it->sync_token = ack.gl_frame_data->sync_token;
-
- if (!is_backbuffer_discarded_) {
- returned_textures_.push(*it);
- } else {
- context_provider_->ContextGL()->DeleteTextures(1, &it->texture_id);
- }
-
- pending_textures_.erase(it);
- } else {
- DCHECK(!pending_textures_.empty());
- // The browser always keeps one texture as the frontbuffer.
- // If it does not return a mailbox, it discarded the frontbuffer which is
- // the oldest texture we sent.
- uint32_t texture_id = pending_textures_.front().texture_id;
- if (texture_id)
- context_provider_->ContextGL()->DeleteTextures(1, &texture_id);
- pending_textures_.pop_front();
- }
- CompositorOutputSurface::OnSwapAck(output_surface_id, ack);
-}
-
-void MailboxOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
- DCHECK(frame->gl_frame_data);
- DCHECK(!surface_size_.IsEmpty());
- DCHECK(surface_size_ == current_backing_.size);
- DCHECK(frame->gl_frame_data->size == current_backing_.size);
- DCHECK(!current_backing_.mailbox.IsZero() ||
- context_provider_->ContextGL()->GetGraphicsResetStatusKHR() !=
- GL_NO_ERROR);
-
- frame->gl_frame_data->mailbox = current_backing_.mailbox;
-
- gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
-
- const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
- gl->Flush();
-
- gl->GenSyncTokenCHROMIUM(fence_sync,
- frame->gl_frame_data->sync_token.GetData());
-
- CompositorOutputSurface::SwapBuffers(frame);
-
- pending_textures_.push_back(current_backing_);
- current_backing_ = TransferableFrame();
-}
-
-size_t MailboxOutputSurface::GetNumAcksPending() {
- DCHECK(pending_textures_.size());
- return pending_textures_.size() - 1;
-}
-
-MailboxOutputSurface::TransferableFrame::TransferableFrame() : texture_id(0) {}
-
-MailboxOutputSurface::TransferableFrame::TransferableFrame(
- uint32_t texture_id,
- const gpu::Mailbox& mailbox,
- const gfx::Size size)
- : texture_id(texture_id), mailbox(mailbox), size(size) {}
-
-} // namespace content
diff --git a/chromium/content/renderer/gpu/mailbox_output_surface.h b/chromium/content/renderer/gpu/mailbox_output_surface.h
deleted file mode 100644
index 1d4b95559f8..00000000000
--- a/chromium/content/renderer/gpu/mailbox_output_surface.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_GPU_MAILBOX_OUTPUT_SURFACE_H_
-#define CONTENT_RENDERER_GPU_MAILBOX_OUTPUT_SURFACE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <queue>
-
-#include "base/memory/ref_counted.h"
-#include "cc/resources/resource_format.h"
-#include "cc/resources/transferable_resource.h"
-#include "content/renderer/gpu/compositor_output_surface.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-class CompositorFrameAck;
-}
-
-namespace content {
-class FrameSwapMessageQueue;
-
-// Implementation of CompositorOutputSurface that renders to textures which
-// are sent to the browser through the mailbox extension.
-// This class can be created only on the main thread, but then becomes pinned
-// to a fixed thread when bindToClient is called.
-class MailboxOutputSurface : public CompositorOutputSurface {
- public:
- MailboxOutputSurface(
- int32_t routing_id,
- uint32_t output_surface_id,
- const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
- const scoped_refptr<ContextProviderCommandBuffer>&
- worker_context_provider,
- scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue,
- cc::ResourceFormat format);
- ~MailboxOutputSurface() override;
-
- // cc::OutputSurface implementation.
- void DetachFromClient() override;
- void EnsureBackbuffer() override;
- void DiscardBackbuffer() override;
- void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override;
- void BindFramebuffer() override;
- void SwapBuffers(cc::CompositorFrame* frame) override;
-
- private:
- // CompositorOutputSurface overrides.
- void OnSwapAck(uint32_t output_surface_id,
- const cc::CompositorFrameAck& ack) override;
-
- size_t GetNumAcksPending();
-
- struct TransferableFrame {
- TransferableFrame();
- TransferableFrame(uint32_t texture_id,
- const gpu::Mailbox& mailbox,
- const gfx::Size size);
-
- uint32_t texture_id;
- gpu::Mailbox mailbox;
- gpu::SyncToken sync_token;
- gfx::Size size;
- };
-
- TransferableFrame current_backing_;
- std::deque<TransferableFrame> pending_textures_;
- std::queue<TransferableFrame> returned_textures_;
-
- uint32_t fbo_;
- bool is_backbuffer_discarded_;
- cc::ResourceFormat format_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_GPU_MAILBOX_OUTPUT_SURFACE_H_
diff --git a/chromium/content/renderer/gpu/queue_message_swap_promise.cc b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
index 9653375e65c..8b99a17256c 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
@@ -4,6 +4,9 @@
#include "content/renderer/gpu/queue_message_swap_promise.h"
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/renderer/render_thread.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "ipc/ipc_sync_message_filter.h"
@@ -38,6 +41,20 @@ void QueueMessageSwapPromise::DidActivate() {
#endif
message_queue_->DidActivate(source_frame_number_);
// The OutputSurface will take care of the Drain+Send.
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseRemoteCompositing)) {
+ // The remote compositing mode doesn't have an output surface, so we need to
+ // Drain+Send on activation. Also, we can't use the SyncMessageFilter, since
+ // this call is actually made on the main thread.
+ std::vector<std::unique_ptr<IPC::Message>> messages_to_deliver;
+ std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
+ send_message_scope = message_queue_->AcquireSendMessageScope();
+ message_queue_->DrainMessages(&messages_to_deliver);
+ for (auto& message : messages_to_deliver)
+ RenderThread::Get()->Send(message.release());
+ PromiseCompleted();
+ }
}
void QueueMessageSwapPromise::DidSwap(cc::CompositorFrameMetadata* metadata) {
diff --git a/chromium/content/renderer/gpu/render_widget_compositor.cc b/chromium/content/renderer/gpu/render_widget_compositor.cc
index 5d5a155fd8b..c73ca064a9d 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor.cc
+++ b/chromium/content/renderer/gpu/render_widget_compositor.cc
@@ -23,6 +23,7 @@
#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_timeline.h"
+#include "cc/animation/layer_tree_mutator.h"
#include "cc/base/switches.h"
#include "cc/blink/web_layer_impl.h"
#include "cc/debug/layer_tree_debug_state.h"
@@ -43,7 +44,6 @@
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "content/common/content_switches_internal.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
-#include "content/common/input/input_event_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/gpu/render_widget_compositor_delegate.h"
@@ -51,6 +51,7 @@
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
+#include "third_party/WebKit/public/platform/WebCompositorMutatorClient.h"
#include "third_party/WebKit/public/platform/WebLayoutAndPaintAsyncCallback.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/web/WebKit.h"
@@ -109,14 +110,14 @@ cc::LayerSelectionBound ConvertWebSelectionBound(
const blink::WebSelectionBound& web_bound =
is_start ? web_selection.start() : web_selection.end();
DCHECK(web_bound.layerId);
- cc_bound.type = cc::SELECTION_BOUND_CENTER;
+ cc_bound.type = gfx::SelectionBound::CENTER;
if (web_selection.isRange()) {
if (is_start) {
- cc_bound.type = web_bound.isTextDirectionRTL ? cc::SELECTION_BOUND_RIGHT
- : cc::SELECTION_BOUND_LEFT;
+ cc_bound.type = web_bound.isTextDirectionRTL ? gfx::SelectionBound::RIGHT
+ : gfx::SelectionBound::LEFT;
} else {
- cc_bound.type = web_bound.isTextDirectionRTL ? cc::SELECTION_BOUND_LEFT
- : cc::SELECTION_BOUND_RIGHT;
+ cc_bound.type = web_bound.isTextDirectionRTL ? gfx::SelectionBound::LEFT
+ : gfx::SelectionBound::RIGHT;
}
}
cc_bound.layer_id = web_bound.layerId;
@@ -220,6 +221,7 @@ RenderWidgetCompositor::RenderWidgetCompositor(
: num_failed_recreate_attempts_(0),
delegate_(delegate),
compositor_deps_(compositor_deps),
+ threaded_(!!compositor_deps_->GetCompositorImplThreadTaskRunner()),
never_visible_(false),
layout_and_paint_async_callback_(nullptr),
remote_proto_channel_receiver_(nullptr),
@@ -227,16 +229,54 @@ RenderWidgetCompositor::RenderWidgetCompositor(
void RenderWidgetCompositor::Initialize(float device_scale_factor) {
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
+ cc::LayerTreeSettings settings =
+ GenerateLayerTreeSettings(*cmd, compositor_deps_, device_scale_factor);
+ cc::LayerTreeHost::InitParams params;
+ params.client = this;
+ params.shared_bitmap_manager = compositor_deps_->GetSharedBitmapManager();
+ params.gpu_memory_buffer_manager =
+ compositor_deps_->GetGpuMemoryBufferManager();
+ params.settings = &settings;
+ params.task_graph_runner = compositor_deps_->GetTaskGraphRunner();
+ params.main_task_runner =
+ compositor_deps_->GetCompositorMainThreadTaskRunner();
+ if (settings.use_external_begin_frame_source) {
+ params.external_begin_frame_source =
+ delegate_->CreateExternalBeginFrameSource();
+ }
+ params.animation_host = cc::AnimationHost::CreateMainInstance();
+
+ if (cmd->HasSwitch(switches::kUseRemoteCompositing)) {
+ DCHECK(!threaded_);
+ params.image_serialization_processor =
+ compositor_deps_->GetImageSerializationProcessor();
+ layer_tree_host_ = cc::LayerTreeHost::CreateRemoteServer(this, &params);
+ } else if (!threaded_) {
+ // Single-threaded layout tests.
+ layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
+ } else {
+ layer_tree_host_ = cc::LayerTreeHost::CreateThreaded(
+ compositor_deps_->GetCompositorImplThreadTaskRunner(), &params);
+ }
+ DCHECK(layer_tree_host_);
+}
+
+RenderWidgetCompositor::~RenderWidgetCompositor() = default;
+// static
+cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
+ const base::CommandLine& cmd,
+ CompositorDependencies* compositor_deps,
+ float device_scale_factor) {
cc::LayerTreeSettings settings;
// For web contents, layer transforms should scale up the contents of layers
// to keep content always crisp when possible.
settings.layer_transforms_should_scale_layer_contents = true;
- if (cmd->HasSwitch(switches::kDisableGpuVsync)) {
+ if (cmd.HasSwitch(switches::kDisableGpuVsync)) {
std::string display_vsync_string =
- cmd->GetSwitchValueASCII(switches::kDisableGpuVsync);
+ cmd.GetSwitchValueASCII(switches::kDisableGpuVsync);
if (display_vsync_string == "gpu") {
settings.renderer_settings.disable_display_vsync = true;
} else if (display_vsync_string == "beginframe") {
@@ -247,38 +287,33 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
}
}
settings.main_frame_before_activation_enabled =
- cmd->HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
- settings.use_mouse_wheel_gestures = UseGestureBasedWheelScrolling();
+ cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
+ // TODO(danakj): This should not be a setting O_O; it should change when the
+ // device scale factor on LayerTreeHost changes.
settings.default_tile_size = CalculateDefaultTileSize(device_scale_factor);
- if (cmd->HasSwitch(switches::kDefaultTileWidth)) {
+ if (cmd.HasSwitch(switches::kDefaultTileWidth)) {
int tile_width = 0;
- GetSwitchValueAsInt(*cmd,
- switches::kDefaultTileWidth,
- 1,
- std::numeric_limits<int>::max(),
- &tile_width);
+ GetSwitchValueAsInt(cmd, switches::kDefaultTileWidth, 1,
+ std::numeric_limits<int>::max(), &tile_width);
settings.default_tile_size.set_width(tile_width);
}
- if (cmd->HasSwitch(switches::kDefaultTileHeight)) {
+ if (cmd.HasSwitch(switches::kDefaultTileHeight)) {
int tile_height = 0;
- GetSwitchValueAsInt(*cmd,
- switches::kDefaultTileHeight,
- 1,
- std::numeric_limits<int>::max(),
- &tile_height);
+ GetSwitchValueAsInt(cmd, switches::kDefaultTileHeight, 1,
+ std::numeric_limits<int>::max(), &tile_height);
settings.default_tile_size.set_height(tile_height);
}
int max_untiled_layer_width = settings.max_untiled_layer_size.width();
- if (cmd->HasSwitch(switches::kMaxUntiledLayerWidth)) {
- GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerWidth, 1,
+ if (cmd.HasSwitch(switches::kMaxUntiledLayerWidth)) {
+ GetSwitchValueAsInt(cmd, switches::kMaxUntiledLayerWidth, 1,
std::numeric_limits<int>::max(),
&max_untiled_layer_width);
}
int max_untiled_layer_height = settings.max_untiled_layer_size.height();
- if (cmd->HasSwitch(switches::kMaxUntiledLayerHeight)) {
- GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerHeight, 1,
+ if (cmd.HasSwitch(switches::kMaxUntiledLayerHeight)) {
+ GetSwitchValueAsInt(cmd, switches::kMaxUntiledLayerHeight, 1,
std::numeric_limits<int>::max(),
&max_untiled_layer_height);
}
@@ -287,50 +322,50 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
max_untiled_layer_height);
settings.gpu_rasterization_msaa_sample_count =
- compositor_deps_->GetGpuRasterizationMSAASampleCount();
+ compositor_deps->GetGpuRasterizationMSAASampleCount();
settings.gpu_rasterization_forced =
- compositor_deps_->IsGpuRasterizationForced();
+ compositor_deps->IsGpuRasterizationForced();
settings.gpu_rasterization_enabled =
- compositor_deps_->IsGpuRasterizationEnabled();
+ compositor_deps->IsGpuRasterizationEnabled();
settings.async_worker_context_enabled =
- compositor_deps_->IsAsyncWorkerContextEnabled();
+ compositor_deps->IsAsyncWorkerContextEnabled();
- settings.can_use_lcd_text = compositor_deps_->IsLcdTextEnabled();
+ settings.can_use_lcd_text = compositor_deps->IsLcdTextEnabled();
settings.use_distance_field_text =
- compositor_deps_->IsDistanceFieldTextEnabled();
- settings.use_zero_copy = compositor_deps_->IsZeroCopyEnabled();
- settings.use_partial_raster = compositor_deps_->IsPartialRasterEnabled();
+ compositor_deps->IsDistanceFieldTextEnabled();
+ settings.use_zero_copy = compositor_deps->IsZeroCopyEnabled();
+ settings.use_partial_raster = compositor_deps->IsPartialRasterEnabled();
settings.enable_elastic_overscroll =
- compositor_deps_->IsElasticOverscrollEnabled();
+ compositor_deps->IsElasticOverscrollEnabled();
settings.renderer_settings.use_gpu_memory_buffer_resources =
- compositor_deps_->IsGpuMemoryBufferCompositorResourcesEnabled();
+ compositor_deps->IsGpuMemoryBufferCompositorResourcesEnabled();
settings.use_image_texture_targets =
- compositor_deps_->GetImageTextureTargets();
+ compositor_deps->GetImageTextureTargets();
settings.image_decode_tasks_enabled =
- compositor_deps_->AreImageDecodeTasksEnabled();
-
- if (cmd->HasSwitch(cc::switches::kTopControlsShowThreshold)) {
- std::string top_threshold_str =
- cmd->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold);
- double show_threshold;
- if (base::StringToDouble(top_threshold_str, &show_threshold) &&
- show_threshold >= 0.f && show_threshold <= 1.f)
- settings.top_controls_show_threshold = show_threshold;
+ compositor_deps->AreImageDecodeTasksEnabled();
+
+ if (cmd.HasSwitch(cc::switches::kTopControlsShowThreshold)) {
+ std::string top_threshold_str =
+ cmd.GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold);
+ double show_threshold;
+ if (base::StringToDouble(top_threshold_str, &show_threshold) &&
+ show_threshold >= 0.f && show_threshold <= 1.f)
+ settings.top_controls_show_threshold = show_threshold;
}
- if (cmd->HasSwitch(cc::switches::kTopControlsHideThreshold)) {
- std::string top_threshold_str =
- cmd->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold);
- double hide_threshold;
- if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
- hide_threshold >= 0.f && hide_threshold <= 1.f)
- settings.top_controls_hide_threshold = hide_threshold;
+ if (cmd.HasSwitch(cc::switches::kTopControlsHideThreshold)) {
+ std::string top_threshold_str =
+ cmd.GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold);
+ double hide_threshold;
+ if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
+ hide_threshold >= 0.f && hide_threshold <= 1.f)
+ settings.top_controls_hide_threshold = hide_threshold;
}
- settings.use_layer_lists = cmd->HasSwitch(cc::switches::kEnableLayerLists);
+ settings.use_layer_lists = cmd.HasSwitch(cc::switches::kEnableLayerLists);
settings.renderer_settings.allow_antialiasing &=
- !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing);
+ !cmd.HasSwitch(cc::switches::kDisableCompositedAntialiasing);
// The means the renderer compositor has 2 possible modes:
// - Threaded compositing with a scheduler.
// - Single threaded compositing without a scheduler (for layout tests only).
@@ -340,30 +375,28 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
// These flags should be mirrored by UI versions in ui/compositor/.
settings.initial_debug_state.show_debug_borders =
- cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders);
+ cmd.HasSwitch(cc::switches::kShowCompositedLayerBorders);
settings.initial_debug_state.show_layer_animation_bounds_rects =
- cmd->HasSwitch(cc::switches::kShowLayerAnimationBounds);
+ cmd.HasSwitch(cc::switches::kShowLayerAnimationBounds);
settings.initial_debug_state.show_paint_rects =
- cmd->HasSwitch(switches::kShowPaintRects);
+ cmd.HasSwitch(switches::kShowPaintRects);
settings.initial_debug_state.show_property_changed_rects =
- cmd->HasSwitch(cc::switches::kShowPropertyChangedRects);
+ cmd.HasSwitch(cc::switches::kShowPropertyChangedRects);
settings.initial_debug_state.show_surface_damage_rects =
- cmd->HasSwitch(cc::switches::kShowSurfaceDamageRects);
+ cmd.HasSwitch(cc::switches::kShowSurfaceDamageRects);
settings.initial_debug_state.show_screen_space_rects =
- cmd->HasSwitch(cc::switches::kShowScreenSpaceRects);
+ cmd.HasSwitch(cc::switches::kShowScreenSpaceRects);
settings.initial_debug_state.show_replica_screen_space_rects =
- cmd->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects);
+ cmd.HasSwitch(cc::switches::kShowReplicaScreenSpaceRects);
settings.initial_debug_state.SetRecordRenderingStats(
- cmd->HasSwitch(cc::switches::kEnableGpuBenchmarking));
+ cmd.HasSwitch(cc::switches::kEnableGpuBenchmarking));
- if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
+ if (cmd.HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
const int kMinSlowDownScaleFactor = 0;
const int kMaxSlowDownScaleFactor = INT_MAX;
GetSwitchValueAsInt(
- *cmd,
- cc::switches::kSlowDownRasterScaleFactor,
- kMinSlowDownScaleFactor,
+ cmd, cc::switches::kSlowDownRasterScaleFactor, kMinSlowDownScaleFactor,
kMaxSlowDownScaleFactor,
&settings.initial_debug_state.slow_down_raster_scale_factor);
}
@@ -403,7 +436,7 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
// RGBA_4444 textures are only enabled by default for low end devices
// and are disabled for Android WebView as it doesn't support the format.
- if (!cmd->HasSwitch(switches::kDisableRGBA4444Textures))
+ if (!cmd.HasSwitch(switches::kDisableRGBA4444Textures))
settings.renderer_settings.preferred_tile_format = cc::RGBA_4444;
} else {
// On other devices we have increased memory excessively to avoid
@@ -420,7 +453,8 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
settings.use_external_begin_frame_source = true;
-#elif !defined(OS_MACOSX)
+#else // defined(OS_ANDROID)
+#if !defined(OS_MACOSX)
if (ui::IsOverlayScrollbarEnabled()) {
settings.scrollbar_animator = cc::LayerTreeSettings::THINNING;
settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
@@ -431,21 +465,36 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
settings.scrollbar_fade_delay_ms = 500;
settings.scrollbar_fade_resize_delay_ms = 500;
settings.scrollbar_fade_duration_ms = 300;
-#endif
+#endif // !defined(OS_MACOSX)
+
+ // On desktop, if there's over 4GB of memory on the machine, increase the
+ // image decode budget to 256MB for both gpu and software.
+ const int kImageDecodeMemoryThresholdMB = 4 * 1024;
+ if (base::SysInfo::AmountOfPhysicalMemoryMB() >=
+ kImageDecodeMemoryThresholdMB) {
+ settings.gpu_decoded_image_budget_bytes = 256 * 1024 * 1024;
+ settings.software_decoded_image_budget_bytes = 256 * 1024 * 1024;
+ } else {
+ // These are the defaults, but recorded here as well.
+ settings.gpu_decoded_image_budget_bytes = 96 * 1024 * 1024;
+ settings.software_decoded_image_budget_bytes = 128 * 1024 * 1024;
+ }
- if (cmd->HasSwitch(switches::kEnableLowResTiling))
+#endif // defined(OS_ANDROID)
+
+ if (cmd.HasSwitch(switches::kEnableLowResTiling))
settings.create_low_res_tiling = true;
- if (cmd->HasSwitch(switches::kDisableLowResTiling))
+ if (cmd.HasSwitch(switches::kDisableLowResTiling))
settings.create_low_res_tiling = false;
- if (cmd->HasSwitch(cc::switches::kEnableBeginFrameScheduling))
+ if (cmd.HasSwitch(cc::switches::kEnableBeginFrameScheduling))
settings.use_external_begin_frame_source = true;
- if (cmd->HasSwitch(switches::kEnableRGBA4444Textures) &&
- !cmd->HasSwitch(switches::kDisableRGBA4444Textures)) {
+ if (cmd.HasSwitch(switches::kEnableRGBA4444Textures) &&
+ !cmd.HasSwitch(switches::kDisableRGBA4444Textures)) {
settings.renderer_settings.preferred_tile_format = cc::RGBA_4444;
}
- if (cmd->HasSwitch(cc::switches::kEnableTileCompression)) {
+ if (cmd.HasSwitch(cc::switches::kEnableTileCompression)) {
settings.renderer_settings.preferred_tile_format = cc::ETC1;
}
@@ -457,55 +506,96 @@ void RenderWidgetCompositor::Initialize(float device_scale_factor) {
cc::ManagedMemoryPolicy current = settings.memory_policy_;
settings.memory_policy_ = GetGpuMemoryPolicy(current);
- settings.use_cached_picture_raster = !cmd->HasSwitch(
- cc::switches::kDisableCachedPictureRaster);
-
- scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner =
- compositor_deps_->GetCompositorImplThreadTaskRunner();
- scoped_refptr<base::SingleThreadTaskRunner>
- main_thread_compositor_task_runner =
- compositor_deps_->GetCompositorMainThreadTaskRunner();
- cc::SharedBitmapManager* shared_bitmap_manager =
- compositor_deps_->GetSharedBitmapManager();
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager =
- compositor_deps_->GetGpuMemoryBufferManager();
- cc::TaskGraphRunner* task_graph_runner =
- compositor_deps_->GetTaskGraphRunner();
-
- bool use_remote_compositing = cmd->HasSwitch(switches::kUseRemoteCompositing);
+ settings.use_cached_picture_raster =
+ !cmd.HasSwitch(cc::switches::kDisableCachedPictureRaster);
- if (use_remote_compositing)
+ if (cmd.HasSwitch(switches::kUseRemoteCompositing))
settings.use_external_begin_frame_source = false;
- std::unique_ptr<cc::BeginFrameSource> external_begin_frame_source;
- if (settings.use_external_begin_frame_source) {
- external_begin_frame_source = delegate_->CreateExternalBeginFrameSource();
+ return settings;
+}
+
+// static
+cc::ManagedMemoryPolicy RenderWidgetCompositor::GetGpuMemoryPolicy(
+ const cc::ManagedMemoryPolicy& policy) {
+ cc::ManagedMemoryPolicy actual = policy;
+ actual.bytes_limit_when_visible = 0;
+
+ // If the value was overridden on the command line, use the specified value.
+ static bool client_hard_limit_bytes_overridden =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceGpuMemAvailableMb);
+ if (client_hard_limit_bytes_overridden) {
+ if (base::StringToSizeT(
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kForceGpuMemAvailableMb),
+ &actual.bytes_limit_when_visible))
+ actual.bytes_limit_when_visible *= 1024 * 1024;
+ return actual;
}
- cc::LayerTreeHost::InitParams params;
- params.client = this;
- params.shared_bitmap_manager = shared_bitmap_manager;
- params.gpu_memory_buffer_manager = gpu_memory_buffer_manager;
- params.settings = &settings;
- params.task_graph_runner = task_graph_runner;
- params.main_task_runner = main_thread_compositor_task_runner;
- params.external_begin_frame_source = std::move(external_begin_frame_source);
- if (use_remote_compositing) {
- DCHECK(!compositor_thread_task_runner.get());
- params.image_serialization_processor =
- compositor_deps_->GetImageSerializationProcessor();
- layer_tree_host_ = cc::LayerTreeHost::CreateRemoteServer(this, &params);
- } else if (compositor_thread_task_runner.get()) {
- layer_tree_host_ = cc::LayerTreeHost::CreateThreaded(
- compositor_thread_task_runner, &params);
- } else {
- layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
+#if defined(OS_ANDROID)
+ // We can't query available GPU memory from the system on Android.
+ // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
+ // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
+ // 128MB java heap size). First we estimate physical memory using both.
+ size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
+ size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
+ size_t physical_memory_mb = 0;
+ if (dalvik_mb >= 256)
+ physical_memory_mb = dalvik_mb * 4;
+ else
+ physical_memory_mb = std::max(dalvik_mb * 4, (physical_mb * 4) / 3);
+
+ // Now we take a default of 1/8th of memory on high-memory devices,
+ // and gradually scale that back for low-memory devices (to be nicer
+ // to other apps so they don't get killed). Examples:
+ // Nexus 4/10(2GB) 256MB (normally 128MB)
+ // Droid Razr M(1GB) 114MB (normally 57MB)
+ // Galaxy Nexus(1GB) 100MB (normally 50MB)
+ // Xoom(1GB) 100MB (normally 50MB)
+ // Nexus S(low-end) 8MB (normally 8MB)
+ // Note that the compositor now uses only some of this memory for
+ // pre-painting and uses the rest only for 'emergencies'.
+ if (actual.bytes_limit_when_visible == 0) {
+ // NOTE: Non-low-end devices use only 50% of these limits,
+ // except during 'emergencies' where 100% can be used.
+ if (!base::SysInfo::IsLowEndDevice()) {
+ if (physical_memory_mb >= 1536)
+ actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB
+ else if (physical_memory_mb >= 1152)
+ actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB
+ else if (physical_memory_mb >= 768)
+ actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB
+ else
+ actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB
+ } else {
+ // Low-end devices have 512MB or less memory by definition
+ // so we hard code the limit rather than relying on the heuristics
+ // above. Low-end devices use 4444 textures so we can use a lower limit.
+ actual.bytes_limit_when_visible = 8;
+ }
+ actual.bytes_limit_when_visible =
+ actual.bytes_limit_when_visible * 1024 * 1024;
+ // Clamp the observed value to a specific range on Android.
+ actual.bytes_limit_when_visible = std::max(
+ actual.bytes_limit_when_visible, static_cast<size_t>(8 * 1024 * 1024));
+ actual.bytes_limit_when_visible =
+ std::min(actual.bytes_limit_when_visible,
+ static_cast<size_t>(256 * 1024 * 1024));
}
- DCHECK(layer_tree_host_);
+ actual.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
+#else
+ // Ignore what the system said and give all clients the same maximum
+ // allocation on desktop platforms.
+ actual.bytes_limit_when_visible = 512 * 1024 * 1024;
+ actual.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
+#endif
+ return actual;
}
-RenderWidgetCompositor::~RenderWidgetCompositor() {}
-
void RenderWidgetCompositor::SetNeverVisible() {
DCHECK(!layer_tree_host_->visible());
never_visible_ = true;
@@ -657,6 +747,10 @@ void RenderWidgetCompositor::startPageScaleAnimation(
duration);
}
+bool RenderWidgetCompositor::hasPendingPageScaleAnimation() const {
+ return layer_tree_host_->HasPendingPageScaleAnimation();
+}
+
void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated(
bool matches_heuristics) {
layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics);
@@ -724,6 +818,12 @@ void RenderWidgetCompositor::clearSelection() {
layer_tree_host_->RegisterSelection(empty_selection);
}
+void RenderWidgetCompositor::setMutatorClient(
+ std::unique_ptr<blink::WebCompositorMutatorClient> client) {
+ TRACE_EVENT0("compositor-worker", "RenderWidgetCompositor::setMutatorClient");
+ layer_tree_host_->SetLayerTreeMutator(std::move(client));
+}
+
static_assert(static_cast<cc::EventListenerClass>(
blink::WebEventListenerClass::TouchStartOrMove) ==
cc::EventListenerClass::kTouchStartOrMove,
@@ -786,8 +886,11 @@ void CompositeAndReadbackAsyncCallback(
}
bool RenderWidgetCompositor::CompositeIsSynchronous() const {
- return !compositor_deps_->GetCompositorImplThreadTaskRunner().get() &&
- !layer_tree_host_->settings().single_thread_proxy_scheduler;
+ if (!threaded_) {
+ DCHECK(!layer_tree_host_->settings().single_thread_proxy_scheduler);
+ return true;
+ }
+ return false;
}
void RenderWidgetCompositor::layoutAndPaintAsync(
@@ -989,8 +1092,7 @@ void RenderWidgetCompositor::DidCommitAndDrawFrame() {
void RenderWidgetCompositor::DidCompleteSwapBuffers() {
delegate_->DidCompleteSwapBuffers();
- bool threaded = !!compositor_deps_->GetCompositorImplThreadTaskRunner().get();
- if (!threaded)
+ if (!threaded_)
delegate_->OnSwapBuffersComplete();
}
@@ -998,13 +1100,6 @@ void RenderWidgetCompositor::DidCompletePageScaleAnimation() {
delegate_->DidCompletePageScaleAnimation();
}
-void RenderWidgetCompositor::ReportFixedRasterScaleUseCounters(
- bool has_blurry_content,
- bool has_potential_performance_regression) {
- delegate_->ReportFixedRasterScaleUseCounters(
- has_blurry_content, has_potential_performance_regression);
-}
-
void RenderWidgetCompositor::RequestScheduleAnimation() {
delegate_->RequestScheduleAnimation();
}
@@ -1050,86 +1145,6 @@ void RenderWidgetCompositor::OnHandleCompositorProto(
remote_proto_channel_receiver_->OnProtoReceived(std::move(deserialized));
}
-cc::ManagedMemoryPolicy RenderWidgetCompositor::GetGpuMemoryPolicy(
- const cc::ManagedMemoryPolicy& policy) {
- cc::ManagedMemoryPolicy actual = policy;
- actual.bytes_limit_when_visible = 0;
-
- // If the value was overridden on the command line, use the specified value.
- static bool client_hard_limit_bytes_overridden =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceGpuMemAvailableMb);
- if (client_hard_limit_bytes_overridden) {
- if (base::StringToSizeT(
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kForceGpuMemAvailableMb),
- &actual.bytes_limit_when_visible))
- actual.bytes_limit_when_visible *= 1024 * 1024;
- return actual;
- }
-
-#if defined(OS_ANDROID)
- // We can't query available GPU memory from the system on Android.
- // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
- // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
- // 128MB java heap size). First we estimate physical memory using both.
- size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
- size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
- size_t physical_memory_mb = 0;
- if (dalvik_mb >= 256)
- physical_memory_mb = dalvik_mb * 4;
- else
- physical_memory_mb = std::max(dalvik_mb * 4, (physical_mb * 4) / 3);
-
- // Now we take a default of 1/8th of memory on high-memory devices,
- // and gradually scale that back for low-memory devices (to be nicer
- // to other apps so they don't get killed). Examples:
- // Nexus 4/10(2GB) 256MB (normally 128MB)
- // Droid Razr M(1GB) 114MB (normally 57MB)
- // Galaxy Nexus(1GB) 100MB (normally 50MB)
- // Xoom(1GB) 100MB (normally 50MB)
- // Nexus S(low-end) 8MB (normally 8MB)
- // Note that the compositor now uses only some of this memory for
- // pre-painting and uses the rest only for 'emergencies'.
- if (actual.bytes_limit_when_visible == 0) {
- // NOTE: Non-low-end devices use only 50% of these limits,
- // except during 'emergencies' where 100% can be used.
- if (!base::SysInfo::IsLowEndDevice()) {
- if (physical_memory_mb >= 1536)
- actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB
- else if (physical_memory_mb >= 1152)
- actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB
- else if (physical_memory_mb >= 768)
- actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB
- else
- actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB
- } else {
- // Low-end devices have 512MB or less memory by definition
- // so we hard code the limit rather than relying on the heuristics
- // above. Low-end devices use 4444 textures so we can use a lower limit.
- actual.bytes_limit_when_visible = 8;
- }
- actual.bytes_limit_when_visible =
- actual.bytes_limit_when_visible * 1024 * 1024;
- // Clamp the observed value to a specific range on Android.
- actual.bytes_limit_when_visible = std::max(
- actual.bytes_limit_when_visible, static_cast<size_t>(8 * 1024 * 1024));
- actual.bytes_limit_when_visible =
- std::min(actual.bytes_limit_when_visible,
- static_cast<size_t>(256 * 1024 * 1024));
- }
- actual.priority_cutoff_when_visible =
- gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
-#else
- // Ignore what the system said and give all clients the same maximum
- // allocation on desktop platforms.
- actual.bytes_limit_when_visible = 512 * 1024 * 1024;
- actual.priority_cutoff_when_visible =
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
-#endif
- return actual;
-}
-
void RenderWidgetCompositor::SetPaintedDeviceScaleFactor(
float device_scale) {
layer_tree_host_->SetPaintedDeviceScaleFactor(device_scale);
diff --git a/chromium/content/renderer/gpu/render_widget_compositor.h b/chromium/content/renderer/gpu/render_widget_compositor.h
index 3b8637ebf8e..68349ec2b9a 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor.h
+++ b/chromium/content/renderer/gpu/render_widget_compositor.h
@@ -22,11 +22,10 @@
#include "content/common/content_export.h"
#include "content/renderer/gpu/compositor_dependencies.h"
#include "third_party/WebKit/public/platform/WebLayerTreeView.h"
-#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/rect.h"
-namespace ui {
-class LatencyInfo;
+namespace base {
+class CommandLine;
}
namespace cc {
@@ -34,11 +33,13 @@ class CopyOutputRequest;
class InputHandler;
class Layer;
class LayerTreeHost;
-
namespace proto {
class CompositorMessage;
}
+}
+namespace ui {
+class LatencyInfo;
}
namespace content {
@@ -60,6 +61,13 @@ class CONTENT_EXPORT RenderWidgetCompositor
~RenderWidgetCompositor() override;
+ static cc::LayerTreeSettings GenerateLayerTreeSettings(
+ const base::CommandLine& cmd,
+ CompositorDependencies* compositor_deps,
+ float device_scale_factor);
+ static cc::ManagedMemoryPolicy GetGpuMemoryPolicy(
+ const cc::ManagedMemoryPolicy& policy);
+
void SetNeverVisible();
const base::WeakPtr<cc::InputHandler>& GetInputHandler();
bool BeginMainFrameRequested() const;
@@ -91,8 +99,6 @@ class CONTENT_EXPORT RenderWidgetCompositor
bool SendMessageToMicroBenchmark(int id, std::unique_ptr<base::Value> value);
void SetSurfaceIdNamespace(uint32_t surface_id_namespace);
void OnHandleCompositorProto(const std::vector<uint8_t>& proto);
- cc::ManagedMemoryPolicy GetGpuMemoryPolicy(
- const cc::ManagedMemoryPolicy& policy);
void SetPaintedDeviceScaleFactor(float device_scale);
// WebLayerTreeView implementation.
@@ -116,6 +122,7 @@ class CONTENT_EXPORT RenderWidgetCompositor
bool use_anchor,
float new_page_scale,
double duration_sec) override;
+ bool hasPendingPageScaleAnimation() const override;
void heuristicsForGpuRasterizationUpdated(bool matches_heuristics) override;
void setNeedsAnimate() override;
void setNeedsBeginFrame() override;
@@ -134,6 +141,8 @@ class CONTENT_EXPORT RenderWidgetCompositor
void clearViewportLayers() override;
void registerSelection(const blink::WebSelection& selection) override;
void clearSelection() override;
+ void setMutatorClient(
+ std::unique_ptr<blink::WebCompositorMutatorClient>) override;
void setEventListenerProperties(
blink::WebEventListenerClass eventClass,
blink::WebEventListenerProperties properties) override;
@@ -172,9 +181,6 @@ class CONTENT_EXPORT RenderWidgetCompositor
void DidCommitAndDrawFrame() override;
void DidCompleteSwapBuffers() override;
void DidCompletePageScaleAnimation() override;
- void ReportFixedRasterScaleUseCounters(
- bool has_blurry_content,
- bool has_potential_performance_regression) override;
// cc::LayerTreeHostSingleThreadClient implementation.
void RequestScheduleAnimation() override;
@@ -208,6 +214,7 @@ class CONTENT_EXPORT RenderWidgetCompositor
int num_failed_recreate_attempts_;
RenderWidgetCompositorDelegate* const delegate_;
CompositorDependencies* const compositor_deps_;
+ const bool threaded_;
std::unique_ptr<cc::LayerTreeHost> layer_tree_host_;
bool never_visible_;
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h b/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
index c688ef9fdad..e31e19e26b5 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
+++ b/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
@@ -83,12 +83,6 @@ class CONTENT_EXPORT RenderWidgetCompositorDelegate {
// perform actual painting work.
virtual void WillBeginCompositorFrame() = 0;
- // Indicates that the last commit would have a blurry content or potential
- // performance regression in a fixed raster scale layer.
- virtual void ReportFixedRasterScaleUseCounters(
- bool has_blurry_content,
- bool has_potential_performance_regression) = 0;
-
protected:
virtual ~RenderWidgetCompositorDelegate() {}
};
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc b/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
index 11c3a575a4c..6dae54c12f7 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ b/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -13,6 +13,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "cc/output/begin_frame_args.h"
#include "cc/test/failure_output_surface.h"
+#include "cc/test/fake_external_begin_frame_source.h"
#include "cc/trees/layer_tree_host.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "content/public/test/mock_render_thread.h"
@@ -29,89 +30,112 @@ using testing::Field;
namespace content {
namespace {
-class MockWebWidget : public blink::WebWidget {
+class StubRenderWidgetCompositorDelegate
+ : public RenderWidgetCompositorDelegate {
public:
- MOCK_METHOD1(beginFrame, void(double lastFrameTimeMonotonic));
-};
-
-class TestRenderWidget : public RenderWidget {
- public:
- explicit TestRenderWidget(CompositorDependencies* compositor_deps)
- : RenderWidget(compositor_deps,
- blink::WebPopupTypeNone,
- blink::WebScreenInfo(),
- true,
- false,
- false) {
- webwidget_ = &mock_webwidget_;
- SetRoutingID(++next_routing_id_);
+ // RenderWidgetCompositorDelegate implementation.
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
+ float page_scale,
+ float top_controls_delta) override {}
+ void BeginMainFrame(double frame_time_sec) override {}
+ std::unique_ptr<cc::OutputSurface> CreateOutputSurface(
+ bool fallback) override {
+ return nullptr;
}
-
- MockWebWidget mock_webwidget_;
-
- protected:
- ~TestRenderWidget() override { webwidget_ = NULL; }
- static int next_routing_id_;
-
- DISALLOW_COPY_AND_ASSIGN(TestRenderWidget);
+ std::unique_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource()
+ override {
+ return nullptr;
+ }
+ void DidCommitAndDrawCompositorFrame() override {}
+ void DidCommitCompositorFrame() override {}
+ void DidCompletePageScaleAnimation() override {}
+ void DidCompleteSwapBuffers() override {}
+ void ForwardCompositorProto(const std::vector<uint8_t>& proto) override {}
+ bool IsClosing() const override { return false; }
+ void OnSwapBuffersAborted() override {}
+ void OnSwapBuffersComplete() override {}
+ void OnSwapBuffersPosted() override {}
+ void RequestScheduleAnimation() override {}
+ void UpdateVisualState() override {}
+ void WillBeginCompositorFrame() override {}
};
-int TestRenderWidget::next_routing_id_ = 0;
-
-class RenderWidgetCompositorTest : public testing::Test {
+class FakeRenderWidgetCompositorDelegate
+ : public StubRenderWidgetCompositorDelegate {
public:
- RenderWidgetCompositorTest()
- : compositor_deps_(new FakeCompositorDependencies),
- render_widget_(new TestRenderWidget(compositor_deps_.get())),
- render_widget_compositor_(RenderWidgetCompositor::Create(
- render_widget_.get(),
- 1.f /* initial_device_scale_factor */,
- compositor_deps_.get())) {}
- ~RenderWidgetCompositorTest() override {}
+ FakeRenderWidgetCompositorDelegate() = default;
- protected:
- base::MessageLoop loop_;
- MockRenderThread render_thread_;
- std::unique_ptr<FakeCompositorDependencies> compositor_deps_;
- scoped_refptr<TestRenderWidget> render_widget_;
- std::unique_ptr<RenderWidgetCompositor> render_widget_compositor_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorTest);
-};
-
-TEST_F(RenderWidgetCompositorTest, BeginMainFrame) {
- base::TimeTicks frame_time(base::TimeTicks() +
- base::TimeDelta::FromSeconds(1));
- base::TimeTicks deadline(base::TimeTicks() + base::TimeDelta::FromSeconds(2));
- base::TimeDelta interval(base::TimeDelta::FromSeconds(3));
- cc::BeginFrameArgs args(
- cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
- interval, cc::BeginFrameArgs::NORMAL));
+ std::unique_ptr<cc::OutputSurface> CreateOutputSurface(
+ bool fallback) override {
+ EXPECT_EQ(
+ num_requests_since_last_success_ >
+ RenderWidgetCompositor::OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
+ fallback);
+ last_create_was_fallback_ = fallback;
+ bool success = num_failures_ >= num_failures_before_success_;
+ if (success) {
+ std::unique_ptr<cc::TestWebGraphicsContext3D> context =
+ cc::TestWebGraphicsContext3D::Create();
+ // Image support required for synchronous compositing.
+ context->set_support_image(true);
+ // Create delegating surface so that max_pending_frames = 1.
+ return cc::FakeOutputSurface::CreateDelegating3d(std::move(context));
+ }
+ return use_null_output_surface_
+ ? nullptr
+ : base::WrapUnique(new cc::FailureOutputSurface(true));
+ }
- EXPECT_CALL(render_widget_->mock_webwidget_, beginFrame(1));
+ std::unique_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource()
+ override {
+ double refresh_rate = 200.0;
+ bool tick_automatically = true;
+ return base::MakeUnique<cc::FakeExternalBeginFrameSource>(
+ refresh_rate, tick_automatically);
+ }
- render_widget_compositor_->BeginMainFrame(args);
-}
+ void add_success() {
+ if (last_create_was_fallback_)
+ ++num_fallback_successes_;
+ else
+ ++num_successes_;
+ num_requests_since_last_success_ = 0;
+ }
+ int num_successes() const { return num_successes_; }
+ int num_fallback_successes() const { return num_fallback_successes_; }
-class RenderWidgetCompositorOutputSurface;
+ void add_request() {
+ ++num_requests_since_last_success_;
+ ++num_requests_;
+ }
+ int num_requests() const { return num_requests_; }
-class RenderWidgetOutputSurface : public TestRenderWidget {
- public:
- explicit RenderWidgetOutputSurface(CompositorDependencies* compositor_deps)
- : TestRenderWidget(compositor_deps), compositor_(NULL) {}
- void SetCompositor(RenderWidgetCompositorOutputSurface* compositor);
+ void add_failure() { ++num_failures_; }
+ int num_failures() const { return num_failures_; }
- std::unique_ptr<cc::OutputSurface> CreateOutputSurface(
- bool fallback) override;
+ void set_num_failures_before_success(int n) {
+ num_failures_before_success_ = n;
+ }
+ int num_failures_before_success() const {
+ return num_failures_before_success_;
+ }
- protected:
- ~RenderWidgetOutputSurface() override {}
+ void set_use_null_output_surface(bool u) { use_null_output_surface_ = u; }
+ bool use_null_output_surface() const { return use_null_output_surface_; }
private:
- RenderWidgetCompositorOutputSurface* compositor_;
-
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetOutputSurface);
+ int num_requests_ = 0;
+ int num_requests_since_last_success_ = 0;
+ int num_failures_ = 0;
+ int num_failures_before_success_ = 0;
+ int num_fallback_successes_ = 0;
+ int num_successes_ = 0;
+ bool last_create_was_fallback_ = false;
+ bool use_null_output_surface_ = true;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeRenderWidgetCompositorDelegate);
};
// Verify that failing to create an output surface will cause the compositor
@@ -122,42 +146,14 @@ class RenderWidgetOutputSurface : public TestRenderWidget {
// the compositor (couldn't bind the output surface) are handled identically.
class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
public:
- RenderWidgetCompositorOutputSurface(RenderWidget* widget,
- CompositorDependencies* compositor_deps)
- : RenderWidgetCompositor(widget, compositor_deps),
- num_failures_before_success_(0),
- expected_successes_(0),
- expected_fallback_successes_(0),
- expected_requests_(0),
- num_requests_(0),
- num_requests_since_last_success_(0),
- num_successes_(0),
- num_fallback_successes_(0),
- num_failures_(0),
- last_create_was_fallback_(false),
- use_null_output_surface_(true) {}
+ RenderWidgetCompositorOutputSurface(
+ FakeRenderWidgetCompositorDelegate* delegate,
+ CompositorDependencies* compositor_deps)
+ : RenderWidgetCompositor(delegate, compositor_deps),
+ delegate_(delegate) {}
using RenderWidgetCompositor::Initialize;
- std::unique_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback) {
- EXPECT_EQ(num_requests_since_last_success_ >
- OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK,
- fallback);
- last_create_was_fallback_ = fallback;
- bool success = num_failures_ >= num_failures_before_success_;
- if (success) {
- std::unique_ptr<cc::TestWebGraphicsContext3D> context =
- cc::TestWebGraphicsContext3D::Create();
- // Image support required for synchronous compositing.
- context->set_support_image(true);
- // Create delegating surface so that max_pending_frames = 1.
- return cc::FakeOutputSurface::CreateDelegating3d(std::move(context));
- }
- return use_null_output_surface_
- ? nullptr
- : base::WrapUnique(new cc::FailureOutputSurface(true));
- }
-
// Force a new output surface to be created.
void SynchronousComposite() {
layer_tree_host()->DidLoseOutputSurface();
@@ -167,21 +163,15 @@ class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
}
void RequestNewOutputSurface() override {
- ++num_requests_;
- ++num_requests_since_last_success_;
+ delegate_->add_request();
RenderWidgetCompositor::RequestNewOutputSurface();
}
void DidInitializeOutputSurface() override {
- if (last_create_was_fallback_)
- ++num_fallback_successes_;
- else
- ++num_successes_;
-
- if (num_requests_ == expected_requests_) {
+ delegate_->add_success();
+ if (delegate_->num_requests() == expected_requests_) {
EndTest();
} else {
- num_requests_since_last_success_ = 0;
RenderWidgetCompositor::DidInitializeOutputSurface();
// Post the synchronous composite task so that it is not called
// reentrantly as a part of RequestNewOutputSurface.
@@ -193,8 +183,8 @@ class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
}
void DidFailToInitializeOutputSurface() override {
- ++num_failures_;
- if (num_requests_ == expected_requests_) {
+ delegate_->add_failure();
+ if (delegate_->num_requests() == expected_requests_) {
EndTest();
return;
}
@@ -202,39 +192,29 @@ class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
RenderWidgetCompositor::DidFailToInitializeOutputSurface();
}
- void SetUp(bool use_null_output_surface,
- int num_failures_before_success,
- int expected_successes,
- int expected_fallback_succeses) {
- use_null_output_surface_ = use_null_output_surface;
- num_failures_before_success_ = num_failures_before_success;
+ void SetUp(int expected_successes, int expected_fallback_succeses) {
expected_successes_ = expected_successes;
expected_fallback_successes_ = expected_fallback_succeses;
- expected_requests_ = num_failures_before_success_ + expected_successes_ +
- expected_fallback_successes_;
+ expected_requests_ = delegate_->num_failures_before_success() +
+ expected_successes_ + expected_fallback_successes_;
}
void EndTest() { base::MessageLoop::current()->QuitWhenIdle(); }
void AfterTest() {
- EXPECT_EQ(num_failures_before_success_, num_failures_);
- EXPECT_EQ(expected_successes_, num_successes_);
- EXPECT_EQ(expected_fallback_successes_, num_fallback_successes_);
- EXPECT_EQ(expected_requests_, num_requests_);
+ EXPECT_EQ(delegate_->num_failures_before_success(),
+ delegate_->num_failures());
+ EXPECT_EQ(expected_successes_, delegate_->num_successes());
+ EXPECT_EQ(expected_fallback_successes_,
+ delegate_->num_fallback_successes());
+ EXPECT_EQ(expected_requests_, delegate_->num_requests());
}
private:
- int num_failures_before_success_;
- int expected_successes_;
- int expected_fallback_successes_;
- int expected_requests_;
- int num_requests_;
- int num_requests_since_last_success_;
- int num_successes_;
- int num_fallback_successes_;
- int num_failures_;
- bool last_create_was_fallback_;
- bool use_null_output_surface_;
+ FakeRenderWidgetCompositorDelegate* delegate_;
+ int expected_successes_ = 0;
+ int expected_fallback_successes_ = 0;
+ int expected_requests_ = 0;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorOutputSurface);
};
@@ -242,53 +222,39 @@ class RenderWidgetCompositorOutputSurface : public RenderWidgetCompositor {
class RenderWidgetCompositorOutputSurfaceTest : public testing::Test {
public:
RenderWidgetCompositorOutputSurfaceTest()
- : compositor_deps_(new FakeCompositorDependencies),
- render_widget_(new RenderWidgetOutputSurface(compositor_deps_.get())) {
- render_widget_compositor_.reset(new RenderWidgetCompositorOutputSurface(
- render_widget_.get(), compositor_deps_.get()));
- render_widget_compositor_->Initialize(
- 1.f /* initial_device_scale_factor */);
- render_widget_->SetCompositor(render_widget_compositor_.get());
+ : render_widget_compositor_(&compositor_delegate_, &compositor_deps_) {
+ render_widget_compositor_.Initialize(1.f /* initial_device_scale_factor */);
}
void RunTest(bool use_null_output_surface,
int num_failures_before_success,
int expected_successes,
int expected_fallback_succeses) {
- render_widget_compositor_->SetUp(
- use_null_output_surface, num_failures_before_success,
- expected_successes, expected_fallback_succeses);
- render_widget_compositor_->setVisible(true);
+ compositor_delegate_.set_use_null_output_surface(use_null_output_surface);
+ compositor_delegate_.set_num_failures_before_success(
+ num_failures_before_success);
+ render_widget_compositor_.SetUp(expected_successes,
+ expected_fallback_succeses);
+ render_widget_compositor_.setVisible(true);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&RenderWidgetCompositorOutputSurface::SynchronousComposite,
- base::Unretained(render_widget_compositor_.get())));
+ base::Unretained(&render_widget_compositor_)));
base::MessageLoop::current()->Run();
- render_widget_compositor_->AfterTest();
+ render_widget_compositor_.AfterTest();
}
protected:
base::MessageLoop ye_olde_message_loope_;
MockRenderThread render_thread_;
- std::unique_ptr<FakeCompositorDependencies> compositor_deps_;
- scoped_refptr<RenderWidgetOutputSurface> render_widget_;
- std::unique_ptr<RenderWidgetCompositorOutputSurface>
- render_widget_compositor_;
+ FakeCompositorDependencies compositor_deps_;
+ FakeRenderWidgetCompositorDelegate compositor_delegate_;
+ RenderWidgetCompositorOutputSurface render_widget_compositor_;
private:
DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositorOutputSurfaceTest);
};
-std::unique_ptr<cc::OutputSurface>
-RenderWidgetOutputSurface::CreateOutputSurface(bool fallback) {
- return compositor_->CreateOutputSurface(fallback);
-}
-
-void RenderWidgetOutputSurface::SetCompositor(
- RenderWidgetCompositorOutputSurface* compositor) {
- compositor_ = compositor;
-}
-
TEST_F(RenderWidgetCompositorOutputSurfaceTest, SucceedOnce) {
RunTest(false, 0, 1, 0);
}
diff --git a/chromium/content/renderer/history_controller.cc b/chromium/content/renderer/history_controller.cc
index 8f1bc3462f7..14ced356b88 100644
--- a/chromium/content/renderer/history_controller.cc
+++ b/chromium/content/renderer/history_controller.cc
@@ -196,8 +196,32 @@ void HistoryController::UpdateForCommit(RenderFrameImpl* frame,
bool navigation_within_page) {
switch (commit_type) {
case blink::WebBackForwardCommit:
- if (!provisional_entry_)
+ if (!provisional_entry_) {
+ // The provisional entry may have been discarded due to a navigation in
+ // a different frame. For main frames, it is not safe to leave the
+ // current_entry_ in place, which may have a cross-site page and will be
+ // included in the PageState for this commit. Replace it with a new
+ // HistoryEntry corresponding to the commit, and clear any stale
+ // NavigationParams which might point to the wrong entry.
+ //
+ // This will lack any subframe history items that were in the original
+ // provisional entry, but we don't know what those were after discarding
+ // it. We'll load the default URL in those subframes instead.
+ //
+ // TODO(creis): It's also possible to get here for subframe commits.
+ // We'll leave a stale current_entry_ in that case, but that only causes
+ // an earlier URL to load in the subframe when leaving and coming back,
+ // and only in rare cases. It does not risk a URL spoof, unlike the
+ // main frame case. Since this bug is not present in the new
+ // FrameNavigationEntry-based navigation path (https://crbug.com/236848)
+ // we'll wait for that to fix the subframe case.
+ if (frame->IsMainFrame()) {
+ current_entry_.reset(new HistoryEntry(item));
+ navigation_params_.reset();
+ }
+
return;
+ }
// If the current entry is null, this must be a main frame commit.
DCHECK(current_entry_ || frame->IsMainFrame());
@@ -230,6 +254,13 @@ void HistoryController::UpdateForCommit(RenderFrameImpl* frame,
if (HistoryEntry::HistoryNode* node =
current_entry_->GetHistoryNodeForFrame(frame)) {
+ // Clear the children and any NavigationParams if this commit isn't for
+ // the same item. Otherwise we might have stale data from a race.
+ if (node->item().itemSequenceNumber() != item.itemSequenceNumber()) {
+ node->RemoveChildren();
+ navigation_params_.reset();
+ }
+
node->set_item(item);
}
break;
diff --git a/chromium/content/renderer/history_controller.h b/chromium/content/renderer/history_controller.h
index ff205967014..ac522418889 100644
--- a/chromium/content/renderer/history_controller.h
+++ b/chromium/content/renderer/history_controller.h
@@ -153,11 +153,15 @@ class CONTENT_EXPORT HistoryController {
// A HistoryEntry representing the page that is being loaded, or an empty
// scoped_ptr if no page is being loaded.
std::unique_ptr<HistoryEntry> provisional_entry_;
- // The NavigationParams corresponding to the last load that was initiated by
- // |GoToEntry|. This is kept around so that it can be passed into existing
- // frames modified during a history navigation in GoToEntry(), and can be
+
+ // The NavigationParams corresponding to the last back/forward load that was
+ // initiated by |GoToEntry|. This is kept around so that it can be passed into
+ // existing frames affected by a history navigation in GoToEntry(), and can be
// passed into frames created after the commit that resulted from the
// navigation in GetItemForNewChildFrame().
+ //
+ // This is reset in UpdateForCommit if we see a commit from a different
+ // navigation, to avoid using stale parameters.
std::unique_ptr<NavigationParams> navigation_params_;
DISALLOW_COPY_AND_ASSIGN(HistoryController);
diff --git a/chromium/content/renderer/history_entry.cc b/chromium/content/renderer/history_entry.cc
index edc21f94a08..61bcb3acf9f 100644
--- a/chromium/content/renderer/history_entry.cc
+++ b/chromium/content/renderer/history_entry.cc
@@ -69,8 +69,10 @@ HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace(
// the frame. See https://crbug.com/612713#c12.
const WebHistoryItem& current_item = current_frame->current_history_item();
if (is_target_frame && clone_children_of_target && !current_item.isNull()) {
- new_history_node->item().setDocumentSequenceNumber(
- current_item.documentSequenceNumber());
+ // TODO(creis): Setting the document sequence number here appears to be
+ // unnecessary. Remove this block if this DCHECK never fires.
+ DCHECK_EQ(current_item.documentSequenceNumber(),
+ new_history_node->item().documentSequenceNumber());
}
// TODO(creis): This needs to be updated to handle HistoryEntry in
diff --git a/chromium/content/renderer/history_serialization.cc b/chromium/content/renderer/history_serialization.cc
index 0a4376c023c..ee5981afa3f 100644
--- a/chromium/content/renderer/history_serialization.cc
+++ b/chromium/content/renderer/history_serialization.cc
@@ -6,9 +6,12 @@
#include <stddef.h>
+#include "base/strings/nullable_string16.h"
+#include "content/child/web_url_request_util.h"
#include "content/common/page_state_serialization.h"
#include "content/public/common/page_state.h"
#include "content/renderer/history_entry.h"
+#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/public/platform/WebHTTPBody.h"
#include "third_party/WebKit/public/platform/WebPoint.h"
@@ -17,6 +20,7 @@
#include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
+using blink::WebData;
using blink::WebHTTPBody;
using blink::WebHistoryItem;
using blink::WebSerializedScriptValue;
@@ -33,56 +37,6 @@ void ToNullableString16Vector(const WebVector<WebString>& input,
output->push_back(input[i]);
}
-void ToExplodedHttpBodyElement(const WebHTTPBody::Element& input,
- ExplodedHttpBodyElement* output) {
- switch (input.type) {
- case WebHTTPBody::Element::TypeData:
- output->data.assign(input.data.data(), input.data.size());
- break;
- case WebHTTPBody::Element::TypeFile:
- output->file_path = input.filePath;
- output->file_start = input.fileStart;
- output->file_length = input.fileLength;
- output->file_modification_time = input.modificationTime;
- break;
- case WebHTTPBody::Element::TypeFileSystemURL:
- output->filesystem_url = input.fileSystemURL;
- output->file_start = input.fileStart;
- output->file_length = input.fileLength;
- output->file_modification_time = input.modificationTime;
- break;
- case WebHTTPBody::Element::TypeBlob:
- output->blob_uuid = input.blobUUID.utf8();
- break;
- }
-}
-
-void AppendHTTPBodyElement(const ExplodedHttpBodyElement& element,
- WebHTTPBody* http_body) {
- switch (element.type) {
- case WebHTTPBody::Element::TypeData:
- http_body->appendData(element.data);
- break;
- case WebHTTPBody::Element::TypeFile:
- http_body->appendFileRange(
- element.file_path,
- element.file_start,
- element.file_length,
- element.file_modification_time);
- break;
- case WebHTTPBody::Element::TypeFileSystemURL:
- http_body->appendFileSystemURLRange(
- element.filesystem_url,
- element.file_start,
- element.file_length,
- element.file_modification_time);
- break;
- case WebHTTPBody::Element::TypeBlob:
- http_body->appendBlob(WebString::fromUTF8(element.blob_uuid));
- break;
- }
-}
-
void GenerateFrameStateFromItem(const WebHistoryItem& item,
ExplodedFrameState* state) {
state->url_string = item.urlString();
@@ -102,15 +56,8 @@ void GenerateFrameStateFromItem(const WebHistoryItem& item,
state->http_body.http_content_type = item.httpContentType();
const WebHTTPBody& http_body = item.httpBody();
- state->http_body.is_null = http_body.isNull();
- if (!state->http_body.is_null) {
- state->http_body.identifier = http_body.identifier();
- state->http_body.elements.resize(http_body.elementCount());
- for (size_t i = 0; i < http_body.elementCount(); ++i) {
- WebHTTPBody::Element element;
- http_body.elementAt(i, element);
- ToExplodedHttpBodyElement(element, &state->http_body.elements[i]);
- }
+ if (!http_body.isNull()) {
+ state->http_body.request_body = GetRequestBodyForWebHTTPBody(http_body);
state->http_body.contains_passwords = http_body.containsPasswordData();
}
}
@@ -157,13 +104,9 @@ void RecursivelyGenerateHistoryItem(const ExplodedFrameState& state,
item.setDocumentSequenceNumber(state.document_sequence_number);
item.setHTTPContentType(state.http_body.http_content_type);
- if (!state.http_body.is_null) {
- WebHTTPBody http_body;
- http_body.initialize();
- http_body.setIdentifier(state.http_body.identifier);
- for (size_t i = 0; i < state.http_body.elements.size(); ++i)
- AppendHTTPBodyElement(state.http_body.elements[i], &http_body);
- item.setHTTPBody(http_body);
+ if (state.http_body.request_body != nullptr) {
+ item.setHTTPBody(
+ GetWebHTTPBodyForRequestBody(state.http_body.request_body));
}
node->set_item(item);
diff --git a/chromium/content/renderer/idle_user_detector.cc b/chromium/content/renderer/idle_user_detector.cc
index 9ca35709fbc..a2f2fd0d2b8 100644
--- a/chromium/content/renderer/idle_user_detector.cc
+++ b/chromium/content/renderer/idle_user_detector.cc
@@ -37,4 +37,8 @@ void IdleUserDetector::OnHandleInputEvent(
}
}
+void IdleUserDetector::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/idle_user_detector.h b/chromium/content/renderer/idle_user_detector.h
index cbe85a0f697..8d55af7ddc6 100644
--- a/chromium/content/renderer/idle_user_detector.h
+++ b/chromium/content/renderer/idle_user_detector.h
@@ -29,6 +29,7 @@ class IdleUserDetector : public RenderViewObserver {
private:
// RenderViewObserver implementation:
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
void OnHandleInputEvent(const blink::WebInputEvent* event,
const ui::LatencyInfo& latency_info,
diff --git a/chromium/content/renderer/image_downloader/image_downloader_impl.cc b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
index 0fd476c1ecd..84c13a5f72a 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_impl.cc
+++ b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
@@ -7,17 +7,16 @@
#include <utility>
#include "base/bind.h"
+#include "base/location.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/child/image_decoder.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/fetchers/multi_resolution_image_resource_fetcher.h"
-#include "mojo/common/url_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
#include "net/base/data_url.h"
#include "skia/ext/image_operations.h"
-#include "skia/public/type_converters.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -145,13 +144,11 @@ void ImageDownloaderImpl::OnRenderProcessShutdown() {
}
// ImageDownloader methods:
-void ImageDownloaderImpl::DownloadImage(const mojo::String& url,
+void ImageDownloaderImpl::DownloadImage(const GURL& image_url,
bool is_favicon,
uint32_t max_bitmap_size,
bool bypass_cache,
const DownloadImageCallback& callback) {
- const GURL image_url = url.To<GURL>();
-
std::vector<SkBitmap> result_images;
std::vector<gfx::Size> result_original_image_sizes;
@@ -211,7 +208,7 @@ void ImageDownloaderImpl::DidFetchImage(
std::find(image_fetchers_.begin(), image_fetchers_.end(), fetcher);
if (iter != image_fetchers_.end()) {
image_fetchers_.weak_erase(iter);
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, fetcher);
}
}
@@ -220,9 +217,12 @@ void ImageDownloaderImpl::ReplyDownloadResult(
const std::vector<SkBitmap>& result_images,
const std::vector<gfx::Size>& result_original_image_sizes,
const DownloadImageCallback& callback) {
- callback.Run(http_status_code,
- mojo::Array<skia::mojom::BitmapPtr>::From(result_images),
- mojo::Array<mojo::SizePtr>::From(result_original_image_sizes));
+ callback.Run(http_status_code, mojo::Array<SkBitmap>::From(result_images),
+ result_original_image_sizes);
+}
+
+void ImageDownloaderImpl::OnDestruct() {
+ delete this;
}
} // namespace content
diff --git a/chromium/content/renderer/image_downloader/image_downloader_impl.h b/chromium/content/renderer/image_downloader/image_downloader_impl.h
index 07ba01516fc..cc4a11aba5c 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_impl.h
+++ b/chromium/content/renderer/image_downloader/image_downloader_impl.h
@@ -45,8 +45,11 @@ class ImageDownloaderImpl : public content::mojom::ImageDownloader,
mojo::InterfaceRequest<content::mojom::ImageDownloader> request);
~ImageDownloaderImpl() override;
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// ImageDownloader methods:
- void DownloadImage(const mojo::String& url,
+ void DownloadImage(const GURL& url,
bool is_favicon,
uint32_t max_bitmap_size,
bool bypass_cache,
diff --git a/chromium/content/renderer/input/input_event_filter.cc b/chromium/content/renderer/input/input_event_filter.cc
index 94e5ba2758c..7f7b09fa6c3 100644
--- a/chromium/content/renderer/input/input_event_filter.cc
+++ b/chromium/content/renderer/input/input_event_filter.cc
@@ -4,6 +4,7 @@
#include "content/renderer/input/input_event_filter.h"
+#include <tuple>
#include <utility>
#include "base/auto_reset.h"
@@ -174,9 +175,9 @@ void InputEventFilter::ForwardToHandler(const IPC::Message& message) {
InputMsg_HandleInputEvent::Param params;
if (!InputMsg_HandleInputEvent::Read(&message, &params))
return;
- const WebInputEvent* event = base::get<0>(params);
- ui::LatencyInfo latency_info = base::get<1>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ ui::LatencyInfo latency_info = std::get<1>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
DCHECK(event);
DCHECK(dispatch_type == DISPATCH_TYPE_BLOCKING ||
dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
diff --git a/chromium/content/renderer/input/input_event_filter_unittest.cc b/chromium/content/renderer/input/input_event_filter_unittest.cc
index 9692720a81b..39547e27514 100644
--- a/chromium/content/renderer/input/input_event_filter_unittest.cc
+++ b/chromium/content/renderer/input/input_event_filter_unittest.cc
@@ -5,11 +5,13 @@
#include <stddef.h>
#include <new>
+#include <tuple>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/macros.h"
+#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
@@ -114,7 +116,7 @@ void AddMessagesToFilter(IPC::MessageFilter* message_filter,
for (size_t i = 0; i < events.size(); ++i)
message_filter->OnMessageReceived(events[i]);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
template <typename T>
@@ -191,8 +193,8 @@ TEST_F(InputEventFilterTest, Basic) {
InputHostMsg_HandleInputEvent_ACK::Param params;
EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message, &params));
- WebInputEvent::Type event_type = base::get<0>(params).type;
- InputEventAckState ack_result = base::get<0>(params).state;
+ WebInputEvent::Type event_type = std::get<0>(params).type;
+ InputEventAckState ack_result = std::get<0>(params).state;
EXPECT_EQ(kEvents[i].type, event_type);
EXPECT_EQ(ack_result, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
@@ -217,7 +219,7 @@ TEST_F(InputEventFilterTest, Basic) {
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
+ const WebInputEvent* event = std::get<0>(params);
EXPECT_EQ(kEvents[i].size, event->size);
EXPECT_TRUE(memcmp(&kEvents[i], event, event->size) == 0);
@@ -243,8 +245,8 @@ TEST_F(InputEventFilterTest, Basic) {
InputHostMsg_HandleInputEvent_ACK::Param params;
EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message, &params));
- WebInputEvent::Type event_type = base::get<0>(params).type;
- InputEventAckState ack_result = base::get<0>(params).state;
+ WebInputEvent::Type event_type = std::get<0>(params).type;
+ InputEventAckState ack_result = std::get<0>(params).state;
EXPECT_EQ(kEvents[i].type, event_type);
EXPECT_EQ(ack_result, INPUT_EVENT_ACK_STATE_CONSUMED);
}
@@ -330,7 +332,7 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
// Second event was queued; ack the first.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
ASSERT_EQ(4u, ipc_sink_.message_count());
EXPECT_EQ(2u, message_recorder_.message_count());
@@ -338,13 +340,13 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
// different.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, message_recorder_.message_count());
// The last events will be coalesced.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, message_recorder_.message_count());
// First two messages should be identical.
@@ -354,8 +356,8 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kEvents[i].size, event->size);
kEvents[i].dispatchType =
@@ -373,8 +375,8 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
const WebMouseWheelEvent* event =
- static_cast<const WebMouseWheelEvent*>(base::get<0>(params));
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ static_cast<const WebMouseWheelEvent*>(std::get<0>(params));
+ InputEventDispatchType dispatch_type = std::get<2>(params);
kEvents[2].dispatchType =
WebInputEvent::DispatchType::ListenersNonBlockingPassive;
@@ -411,7 +413,7 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
// Second event was queued; ack the first.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
ASSERT_EQ(4u, ipc_sink_.message_count());
EXPECT_EQ(2u, message_recorder_.message_count());
@@ -419,13 +421,13 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
// different.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::TouchMove,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, message_recorder_.message_count());
// The last events will be coalesced.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::TouchMove,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, message_recorder_.message_count());
// First two messages should be identical.
@@ -435,8 +437,8 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kEvents[i].size, event->size);
kEvents[i].dispatchType =
@@ -454,8 +456,8 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
const WebTouchEvent* event =
- static_cast<const WebTouchEvent*>(base::get<0>(params));
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ static_cast<const WebTouchEvent*>(std::get<0>(params));
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kEvents[3].size, event->size);
EXPECT_EQ(1u, kEvents[3].touchesLength);
@@ -494,8 +496,8 @@ TEST_F(InputEventFilterTest, IntermingledNonBlockingTouch) {
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kEvents[0].size, event->size);
kEvents[0].dispatchType =
@@ -509,15 +511,15 @@ TEST_F(InputEventFilterTest, IntermingledNonBlockingTouch) {
// Second event was queued; ack the first.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, message_recorder_.message_count());
const IPC::Message& message = message_recorder_.message_at(1);
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kEvents[1].size, event->size);
kEvents[1].dispatchType =
@@ -531,15 +533,15 @@ TEST_F(InputEventFilterTest, IntermingledNonBlockingTouch) {
// Third event should be put in the queue.
filter_->NotifyInputEventHandled(kTestRoutingID, WebInputEvent::TouchEnd,
INPUT_EVENT_ACK_STATE_CONSUMED);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, message_recorder_.message_count());
const IPC::Message& message = message_recorder_.message_at(2);
ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
InputMsg_HandleInputEvent::Param params;
EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, &params));
- const WebInputEvent* event = base::get<0>(params);
- InputEventDispatchType dispatch_type = base::get<2>(params);
+ const WebInputEvent* event = std::get<0>(params);
+ InputEventDispatchType dispatch_type = std::get<2>(params);
EXPECT_EQ(kBlockingEvents[0].size, event->size);
EXPECT_TRUE(memcmp(&kBlockingEvents[0], event, event->size) == 0);
diff --git a/chromium/content/renderer/input/input_handler_manager.cc b/chromium/content/renderer/input/input_handler_manager.cc
index 2e28534089f..0821d8225fc 100644
--- a/chromium/content/renderer/input/input_handler_manager.cc
+++ b/chromium/content/renderer/input/input_handler_manager.cc
@@ -67,20 +67,18 @@ void InputHandlerManager::AddInputHandler(
int routing_id,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures) {
+ bool enable_smooth_scrolling) {
if (task_runner_->BelongsToCurrentThread()) {
AddInputHandlerOnCompositorThread(
routing_id, base::ThreadTaskRunnerHandle::Get(), input_handler,
- render_view_impl, enable_smooth_scrolling, enable_wheel_gestures);
+ render_view_impl, enable_smooth_scrolling);
} else {
task_runner_->PostTask(
FROM_HERE,
base::Bind(&InputHandlerManager::AddInputHandlerOnCompositorThread,
base::Unretained(this), routing_id,
base::ThreadTaskRunnerHandle::Get(), input_handler,
- render_view_impl, enable_smooth_scrolling,
- enable_wheel_gestures));
+ render_view_impl, enable_smooth_scrolling));
}
}
@@ -89,8 +87,7 @@ void InputHandlerManager::AddInputHandlerOnCompositorThread(
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures) {
+ bool enable_smooth_scrolling) {
DCHECK(task_runner_->BelongsToCurrentThread());
// The handler could be gone by this point if the compositor has shut down.
@@ -104,9 +101,9 @@ void InputHandlerManager::AddInputHandlerOnCompositorThread(
TRACE_EVENT1("input",
"InputHandlerManager::AddInputHandlerOnCompositorThread",
"result", "AddingRoute");
- std::unique_ptr<InputHandlerWrapper> wrapper(new InputHandlerWrapper(
- this, routing_id, main_task_runner, input_handler, render_view_impl,
- enable_smooth_scrolling, enable_wheel_gestures));
+ std::unique_ptr<InputHandlerWrapper> wrapper(
+ new InputHandlerWrapper(this, routing_id, main_task_runner, input_handler,
+ render_view_impl, enable_smooth_scrolling));
client_->RegisterRoutingID(routing_id);
if (synchronous_handler_proxy_client_) {
synchronous_handler_proxy_client_->DidAddSynchronousHandlerProxy(
@@ -162,32 +159,6 @@ void InputHandlerManager::UnregisterRoutingIDOnCompositorThread(
client_->UnregisterRoutingID(routing_id);
}
-void InputHandlerManager::ObserveWheelEventAndResultOnMainThread(
- int routing_id,
- const blink::WebMouseWheelEvent& wheel_event,
- const cc::InputHandlerScrollResult& scroll_result) {
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread,
- base::Unretained(this), routing_id, wheel_event, scroll_result));
-}
-
-void InputHandlerManager::ObserveWheelEventAndResultOnCompositorThread(
- int routing_id,
- const blink::WebMouseWheelEvent& wheel_event,
- const cc::InputHandlerScrollResult& scroll_result) {
- DCHECK(task_runner_->BelongsToCurrentThread());
- auto it = input_handlers_.find(routing_id);
- if (it == input_handlers_.end())
- return;
-
- InputHandlerProxy* proxy = it->second->input_handler_proxy();
- DCHECK(proxy->scroll_elasticity_controller());
- proxy->scroll_elasticity_controller()->ObserveWheelEventAndResult(
- wheel_event, scroll_result);
-}
-
void InputHandlerManager::ObserveGestureEventAndResultOnMainThread(
int routing_id,
const blink::WebGestureEvent& gesture_event,
diff --git a/chromium/content/renderer/input/input_handler_manager.h b/chromium/content/renderer/input/input_handler_manager.h
index bb3ef894820..1935a2e04a3 100644
--- a/chromium/content/renderer/input/input_handler_manager.h
+++ b/chromium/content/renderer/input/input_handler_manager.h
@@ -56,17 +56,11 @@ class CONTENT_EXPORT InputHandlerManager {
void AddInputHandler(int routing_id,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures);
+ bool enable_smooth_scrolling);
void RegisterRoutingID(int routing_id);
void UnregisterRoutingID(int routing_id);
- void ObserveWheelEventAndResultOnMainThread(
- int routing_id,
- const blink::WebMouseWheelEvent& wheel_event,
- const cc::InputHandlerScrollResult& scroll_result);
-
void ObserveGestureEventAndResultOnMainThread(
int routing_id,
const blink::WebGestureEvent& gesture_event,
@@ -102,8 +96,7 @@ class CONTENT_EXPORT InputHandlerManager {
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures);
+ bool enable_smooth_scrolling);
void RegisterRoutingIDOnCompositorThread(int routing_id);
void UnregisterRoutingIDOnCompositorThread(int routing_id);
diff --git a/chromium/content/renderer/input/input_handler_wrapper.cc b/chromium/content/renderer/input/input_handler_wrapper.cc
index 7678f9337c1..77416f37212 100644
--- a/chromium/content/renderer/input/input_handler_wrapper.cc
+++ b/chromium/content/renderer/input/input_handler_wrapper.cc
@@ -20,8 +20,7 @@ InputHandlerWrapper::InputHandlerWrapper(
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures)
+ bool enable_smooth_scrolling)
: input_handler_manager_(input_handler_manager),
routing_id_(routing_id),
input_handler_proxy_(input_handler.get(), this),
@@ -29,8 +28,6 @@ InputHandlerWrapper::InputHandlerWrapper(
render_view_impl_(render_view_impl) {
DCHECK(input_handler);
input_handler_proxy_.set_smooth_scroll_enabled(enable_smooth_scrolling);
- input_handler_proxy_.set_use_gesture_events_for_mouse_wheel(
- enable_wheel_gestures);
}
InputHandlerWrapper::~InputHandlerWrapper() {
diff --git a/chromium/content/renderer/input/input_handler_wrapper.h b/chromium/content/renderer/input/input_handler_wrapper.h
index 35c96e97dfb..5a9248ed74e 100644
--- a/chromium/content/renderer/input/input_handler_wrapper.h
+++ b/chromium/content/renderer/input/input_handler_wrapper.h
@@ -28,8 +28,7 @@ class InputHandlerWrapper : public ui::InputHandlerProxyClient {
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
const base::WeakPtr<cc::InputHandler>& input_handler,
const base::WeakPtr<RenderViewImpl>& render_view_impl,
- bool enable_smooth_scrolling,
- bool enable_wheel_gestures);
+ bool enable_smooth_scrolling);
~InputHandlerWrapper() override;
int routing_id() const { return routing_id_; }
diff --git a/chromium/content/renderer/input/render_widget_input_handler.cc b/chromium/content/renderer/input/render_widget_input_handler.cc
index 25bd40139ca..878f087f78c 100644
--- a/chromium/content/renderer/input/render_widget_input_handler.cc
+++ b/chromium/content/renderer/input/render_widget_input_handler.cc
@@ -387,21 +387,11 @@ void RenderWidgetInputHandler::HandleInputEvent(
}
}
- // Send mouse wheel events and their disposition to the compositor thread, so
- // that they can be used to produce the elastic overscroll effect on Mac.
- if (input_event.type == WebInputEvent::MouseWheel) {
- const WebMouseWheelEvent& wheel_event =
- static_cast<const WebMouseWheelEvent&>(input_event);
- if (wheel_event.canScroll) {
- delegate_->ObserveWheelEventAndResult(
- wheel_event,
- event_overscroll ? event_overscroll->latest_overscroll_delta
- : gfx::Vector2dF(),
- processed != WebInputEventResult::NotHandled);
- }
- } else if (input_event.type == WebInputEvent::GestureScrollBegin ||
- input_event.type == WebInputEvent::GestureScrollEnd ||
- input_event.type == WebInputEvent::GestureScrollUpdate) {
+ // Send gesture scroll events and their dispositions to the compositor thread,
+ // so that they can be used to produce the elastic overscroll effect on Mac.
+ if (input_event.type == WebInputEvent::GestureScrollBegin ||
+ input_event.type == WebInputEvent::GestureScrollEnd ||
+ input_event.type == WebInputEvent::GestureScrollUpdate) {
const WebGestureEvent& gesture_event =
static_cast<const WebGestureEvent&>(input_event);
if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad) {
diff --git a/chromium/content/renderer/input/render_widget_input_handler_delegate.h b/chromium/content/renderer/input/render_widget_input_handler_delegate.h
index 55465fd5787..bbb58d006be 100644
--- a/chromium/content/renderer/input/render_widget_input_handler_delegate.h
+++ b/chromium/content/renderer/input/render_widget_input_handler_delegate.h
@@ -43,13 +43,6 @@ class CONTENT_EXPORT RenderWidgetInputHandlerDelegate {
// at the given point.
virtual bool HasTouchEventHandlersAt(const gfx::Point& point) const = 0;
- // Called to forward a mouse wheel event to the compositor thread, to effect
- // the elastic overscroll effect.
- virtual void ObserveWheelEventAndResult(
- const blink::WebMouseWheelEvent& wheel_event,
- const gfx::Vector2dF& wheel_unused_delta,
- bool event_processed) = 0;
-
// Called to forward a gesture event to the compositor thread, to effect
// the elastic overscroll effect.
virtual void ObserveGestureEventAndResult(
diff --git a/chromium/content/renderer/java/gin_java_bridge_dispatcher.cc b/chromium/content/renderer/java/gin_java_bridge_dispatcher.cc
index 0d6d07350d1..a7a9a449887 100644
--- a/chromium/content/renderer/java/gin_java_bridge_dispatcher.cc
+++ b/chromium/content/renderer/java/gin_java_bridge_dispatcher.cc
@@ -133,4 +133,8 @@ void GinJavaBridgeDispatcher::OnGinJavaBridgeObjectDeleted(
new GinJavaBridgeHostMsg_ObjectWrapperDeleted(routing_id(), object_id));
}
+void GinJavaBridgeDispatcher::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/java/gin_java_bridge_dispatcher.h b/chromium/content/renderer/java/gin_java_bridge_dispatcher.h
index f795c288f78..297da75247d 100644
--- a/chromium/content/renderer/java/gin_java_bridge_dispatcher.h
+++ b/chromium/content/renderer/java/gin_java_bridge_dispatcher.h
@@ -59,6 +59,9 @@ class GinJavaBridgeDispatcher
void OnGinJavaBridgeObjectDeleted(GinJavaBridgeObject* object);
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
void OnAddNamedObject(const std::string& name,
ObjectID object_id);
void OnRemoveNamedObject(const std::string& name);
diff --git a/chromium/content/renderer/java/gin_java_bridge_value_converter.cc b/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
index 527b541c5b3..309d77d43d8 100644
--- a/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
+++ b/chromium/content/renderer/java/gin_java_bridge_value_converter.cc
@@ -38,20 +38,19 @@ v8::Local<v8::Value> GinJavaBridgeValueConverter::ToV8Value(
std::unique_ptr<base::Value> GinJavaBridgeValueConverter::FromV8Value(
v8::Local<v8::Value> value,
v8::Local<v8::Context> context) const {
- return base::WrapUnique(converter_->FromV8Value(value, context));
+ return converter_->FromV8Value(value, context);
}
bool GinJavaBridgeValueConverter::FromV8Object(
v8::Local<v8::Object> value,
- base::Value** out,
+ std::unique_ptr<base::Value>* out,
v8::Isolate* isolate,
const FromV8ValueCallback& callback) const {
GinJavaBridgeObject* unwrapped;
if (!gin::ConvertFromV8(isolate, value, &unwrapped)) {
return false;
}
- *out =
- GinJavaBridgeValue::CreateObjectIDValue(unwrapped->object_id()).release();
+ *out = GinJavaBridgeValue::CreateObjectIDValue(unwrapped->object_id());
return true;
}
@@ -124,10 +123,10 @@ std::unique_ptr<TypedArraySerializer> TypedArraySerializer::Create(
bool GinJavaBridgeValueConverter::FromV8ArrayBuffer(
v8::Local<v8::Object> value,
- base::Value** out,
+ std::unique_ptr<base::Value>* out,
v8::Isolate* isolate) const {
if (!value->IsTypedArray()) {
- *out = GinJavaBridgeValue::CreateUndefinedValue().release();
+ *out = GinJavaBridgeValue::CreateUndefinedValue();
return true;
}
@@ -139,29 +138,31 @@ bool GinJavaBridgeValueConverter::FromV8ArrayBuffer(
data_length = view.num_bytes();
}
if (!data) {
- *out = GinJavaBridgeValue::CreateUndefinedValue().release();
+ *out = GinJavaBridgeValue::CreateUndefinedValue();
return true;
}
- base::ListValue* result = new base::ListValue();
- *out = result;
+ std::unique_ptr<base::ListValue> result(new base::ListValue);
std::unique_ptr<TypedArraySerializer> serializer(
TypedArraySerializer::Create(value.As<v8::TypedArray>()));
- serializer->serializeTo(data, data_length, result);
+ serializer->serializeTo(data, data_length, result.get());
+ *out = std::move(result);
return true;
}
-bool GinJavaBridgeValueConverter::FromV8Number(v8::Local<v8::Number> value,
- base::Value** out) const {
+bool GinJavaBridgeValueConverter::FromV8Number(
+ v8::Local<v8::Number> value,
+ std::unique_ptr<base::Value>* out) const {
double double_value = value->Value();
if (std::isfinite(double_value))
return false;
- *out = GinJavaBridgeValue::CreateNonFiniteValue(double_value).release();
+ *out = GinJavaBridgeValue::CreateNonFiniteValue(double_value);
return true;
}
-bool GinJavaBridgeValueConverter::FromV8Undefined(base::Value** out) const {
- *out = GinJavaBridgeValue::CreateUndefinedValue().release();
+bool GinJavaBridgeValueConverter::FromV8Undefined(
+ std::unique_ptr<base::Value>* out) const {
+ *out = GinJavaBridgeValue::CreateUndefinedValue();
return true;
}
diff --git a/chromium/content/renderer/java/gin_java_bridge_value_converter.h b/chromium/content/renderer/java/gin_java_bridge_value_converter.h
index 2e48f199db3..9ab3849a3f5 100644
--- a/chromium/content/renderer/java/gin_java_bridge_value_converter.h
+++ b/chromium/content/renderer/java/gin_java_bridge_value_converter.h
@@ -27,15 +27,15 @@ class GinJavaBridgeValueConverter : public content::V8ValueConverter::Strategy {
// content::V8ValueConverter::Strategy
bool FromV8Object(v8::Local<v8::Object> value,
- base::Value** out,
+ std::unique_ptr<base::Value>* out,
v8::Isolate* isolate,
const FromV8ValueCallback& callback) const override;
bool FromV8ArrayBuffer(v8::Local<v8::Object> value,
- base::Value** out,
+ std::unique_ptr<base::Value>* out,
v8::Isolate* isolate) const override;
bool FromV8Number(v8::Local<v8::Number> value,
- base::Value** out) const override;
- bool FromV8Undefined(base::Value** out) const override;
+ std::unique_ptr<base::Value>* out) const override;
+ bool FromV8Undefined(std::unique_ptr<base::Value>* out) const override;
private:
std::unique_ptr<V8ValueConverter> converter_;
diff --git a/chromium/content/renderer/layout_test_dependencies.h b/chromium/content/renderer/layout_test_dependencies.h
new file mode 100644
index 00000000000..743c61d2c7a
--- /dev/null
+++ b/chromium/content/renderer/layout_test_dependencies.h
@@ -0,0 +1,38 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDER_LAYOUT_TEST_DEPENDENCIES_H_
+#define CONTENT_RENDER_LAYOUT_TEST_DEPENDENCIES_H_
+
+#include <stdint.h>
+#include <memory>
+
+#include "base/memory/ref_counted.h"
+
+namespace cc {
+class ContextProvider;
+class OutputSurface;
+}
+
+namespace gpu {
+class GpuChannelHost;
+}
+
+namespace content {
+class CompositorDependencies;
+
+// This class allows injection of LayoutTest-specific behaviour to the
+// RenderThreadImpl.
+class LayoutTestDependencies {
+ public:
+ virtual std::unique_ptr<cc::OutputSurface> CreateOutputSurface(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel,
+ scoped_refptr<cc::ContextProvider> compositor_context_provider,
+ scoped_refptr<cc::ContextProvider> worker_context_provider,
+ CompositorDependencies* deps) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDER_LAYOUT_TEST_DEPENDENCIES_H_
diff --git a/chromium/content/renderer/manifest/manifest_manager.cc b/chromium/content/renderer/manifest/manifest_manager.cc
index 1f9d4ed9bbc..69a75de2500 100644
--- a/chromium/content/renderer/manifest/manifest_manager.cc
+++ b/chromium/content/renderer/manifest/manifest_manager.cc
@@ -206,4 +206,8 @@ void ManifestManager::ResolveCallbacks(ResolveState state) {
}
}
+void ManifestManager::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/manifest/manifest_manager.h b/chromium/content/renderer/manifest/manifest_manager.h
index 6ed61226ef3..554617cdcbe 100644
--- a/chromium/content/renderer/manifest/manifest_manager.h
+++ b/chromium/content/renderer/manifest/manifest_manager.h
@@ -54,6 +54,9 @@ class ManifestManager : public RenderFrameObserver {
ResolveStateFailure
};
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Called when receiving a ManifestManagerMsg_RequestManifest from the browser
// process.
void OnHasManifest(int request_id);
diff --git a/chromium/content/renderer/manifest/manifest_parser.cc b/chromium/content/renderer/manifest/manifest_parser.cc
index 1222a556c48..23dca88bb9b 100644
--- a/chromium/content/renderer/manifest/manifest_parser.cc
+++ b/chromium/content/renderer/manifest/manifest_parser.cc
@@ -17,76 +17,14 @@
#include "content/public/common/manifest.h"
#include "content/renderer/manifest/manifest_uma_util.h"
#include "third_party/WebKit/public/platform/WebColor.h"
+#include "third_party/WebKit/public/platform/WebIconSizesParser.h"
+#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebCSSParser.h"
#include "ui/gfx/geometry/size.h"
namespace content {
-namespace {
-
-// Helper function that returns whether the given |str| is a valid width or
-// height value for an icon sizes per:
-// https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes
-bool IsValidIconWidthOrHeight(const std::string& str) {
- if (str.empty() || str[0] == '0')
- return false;
- for (size_t i = 0; i < str.size(); ++i)
- if (!base::IsAsciiDigit(str[i]))
- return false;
- return true;
-}
-
-// Parses the 'sizes' attribute of an icon as described in the HTML spec:
-// https://html.spec.whatwg.org/multipage/semantics.html#attr-link-sizes
-// Return a vector of gfx::Size that contains the valid sizes found. "Any" is
-// represented by gfx::Size(0, 0).
-// TODO(mlamouri): this is implemented as a separate function because it should
-// be refactored with the other icon sizes parsing implementations, see
-// http://crbug.com/416477
-std::vector<gfx::Size> ParseIconSizesHTML(const base::string16& sizes_str16) {
- if (!base::IsStringASCII(sizes_str16))
- return std::vector<gfx::Size>();
-
- std::vector<gfx::Size> sizes;
- std::string sizes_str =
- base::ToLowerASCII(base::UTF16ToUTF8(sizes_str16));
- std::vector<std::string> sizes_str_list = base::SplitString(
- sizes_str, base::kWhitespaceASCII, base::KEEP_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
-
- for (size_t i = 0; i < sizes_str_list.size(); ++i) {
- std::string& size_str = sizes_str_list[i];
- if (size_str == "any") {
- sizes.push_back(gfx::Size(0, 0));
- continue;
- }
-
- // It is expected that [0] => width and [1] => height after the split.
- std::vector<std::string> size_list = base::SplitString(
- size_str, "x", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
- if (size_list.size() != 2)
- continue;
- if (!IsValidIconWidthOrHeight(size_list[0]) ||
- !IsValidIconWidthOrHeight(size_list[1])) {
- continue;
- }
-
- int width, height;
- if (!base::StringToInt(size_list[0], &width) ||
- !base::StringToInt(size_list[1], &height)) {
- continue;
- }
-
- sizes.push_back(gfx::Size(width, height));
- }
-
- return sizes;
-}
-
-} // anonymous namespace
-
-
ManifestParser::ManifestParser(const base::StringPiece& data,
const GURL& manifest_url,
const GURL& document_url)
@@ -126,6 +64,7 @@ void ManifestParser::Parse() {
manifest_.name = ParseName(*dictionary);
manifest_.short_name = ParseShortName(*dictionary);
manifest_.start_url = ParseStartURL(*dictionary);
+ manifest_.scope = ParseScope(*dictionary, manifest_.start_url);
manifest_.display = ParseDisplay(*dictionary);
manifest_.orientation = ParseOrientation(*dictionary);
manifest_.icons = ParseIcons(*dictionary);
@@ -218,7 +157,10 @@ GURL ManifestParser::ParseURL(const base::DictionaryValue& dictionary,
if (url_str.is_null())
return GURL();
- return base_url.Resolve(url_str.string());
+ GURL resolved = base_url.Resolve(url_str.string());
+ if (!resolved.is_valid())
+ AddErrorInfo("property '" + key + "' ignored, URL is invalid.");
+ return resolved;
}
base::NullableString16 ManifestParser::ParseName(
@@ -245,6 +187,34 @@ GURL ManifestParser::ParseStartURL(const base::DictionaryValue& dictionary) {
return start_url;
}
+GURL ManifestParser::ParseScope(const base::DictionaryValue& dictionary,
+ const GURL& start_url) {
+ GURL scope = ParseURL(dictionary, "scope", manifest_url_);
+ if (!scope.is_valid()) {
+ return GURL();
+ }
+
+ if (scope.GetOrigin() != document_url_.GetOrigin()) {
+ AddErrorInfo("property 'scope' ignored, should be "
+ "same origin as document.");
+ return GURL();
+ }
+
+ // According to the spec, if the start_url cannot be parsed, the document URL
+ // should be used as the start URL. If the start_url could not be parsed,
+ // check that the document URL is within scope.
+ GURL check_in_scope = start_url.is_empty() ? document_url_ : start_url;
+ if (check_in_scope.GetOrigin() != scope.GetOrigin() ||
+ !base::StartsWith(check_in_scope.path(), scope.path(),
+ base::CompareCase::SENSITIVE)) {
+ AddErrorInfo(
+ "property 'scope' ignored. Start url should be within scope "
+ "of scope URL.");
+ return GURL();
+ }
+ return scope;
+}
+
blink::WebDisplayMode ManifestParser::ParseDisplay(
const base::DictionaryValue& dictionary) {
base::NullableString16 display = ParseString(dictionary, "display", Trim);
@@ -311,11 +281,16 @@ base::NullableString16 ManifestParser::ParseIconType(
std::vector<gfx::Size> ManifestParser::ParseIconSizes(
const base::DictionaryValue& icon) {
base::NullableString16 sizes_str = ParseString(icon, "sizes", NoTrim);
+ std::vector<gfx::Size> sizes;
if (sizes_str.is_null())
- return std::vector<gfx::Size>();
+ return sizes;
- std::vector<gfx::Size> sizes = ParseIconSizesHTML(sizes_str.string());
+ blink::WebVector<blink::WebSize> web_sizes =
+ blink::WebIconSizesParser::parseIconSizes(sizes_str.string());
+ sizes.resize(web_sizes.size());
+ for (size_t i = 0; i < web_sizes.size(); ++i)
+ sizes[i] = web_sizes[i];
if (sizes.empty()) {
AddErrorInfo("found icon with no valid size.");
}
diff --git a/chromium/content/renderer/manifest/manifest_parser.h b/chromium/content/renderer/manifest/manifest_parser.h
index 0f12c5a4745..2c8d2076e33 100644
--- a/chromium/content/renderer/manifest/manifest_parser.h
+++ b/chromium/content/renderer/manifest/manifest_parser.h
@@ -90,6 +90,12 @@ class CONTENT_EXPORT ManifestParser {
base::NullableString16 ParseShortName(
const base::DictionaryValue& dictionary);
+ // Parses the 'scope' field of the manifest, as defined in:
+ // http://w3c.github.io/manifest/#dfn-steps-for-processing-the-scope-member
+ // Returns the parsed GURL if any, an empty GURL if the parsing failed.
+ GURL ParseScope(const base::DictionaryValue& dictionary,
+ const GURL& start_url);
+
// Parses the 'start_url' field of the manifest, as defined in:
// http://w3c.github.io/manifest/#dfn-steps-for-processing-the-start_url-member
// Returns the parsed GURL if any, an empty GURL if the parsing failed.
diff --git a/chromium/content/renderer/manifest/manifest_parser_unittest.cc b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
index b86a0e7e6ca..4311531436d 100644
--- a/chromium/content/renderer/manifest/manifest_parser_unittest.cc
+++ b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
@@ -29,9 +29,9 @@ class ManifestParserTest : public testing::Test {
~ManifestParserTest() override {}
Manifest ParseManifestWithURLs(const base::StringPiece& data,
- const GURL& document_url,
- const GURL& manifest_url) {
- ManifestParser parser(data, document_url, manifest_url);
+ const GURL& manifest_url,
+ const GURL& document_url) {
+ ManifestParser parser(data, manifest_url, document_url);
parser.Parse();
std::vector<ManifestDebugInfo::Error> errors;
parser.TakeErrors(&errors);
@@ -44,7 +44,7 @@ class ManifestParserTest : public testing::Test {
Manifest ParseManifest(const base::StringPiece& data) {
return ParseManifestWithURLs(
- data, default_document_url, default_manifest_url);
+ data, default_manifest_url, default_document_url);
}
const std::vector<std::string>& errors() const {
@@ -101,6 +101,7 @@ TEST_F(ManifestParserTest, EmptyStringNull) {
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
+ ASSERT_TRUE(manifest.scope.is_empty());
}
TEST_F(ManifestParserTest, ValidNoContentParses) {
@@ -119,6 +120,7 @@ TEST_F(ManifestParserTest, ValidNoContentParses) {
ASSERT_EQ(manifest.theme_color, Manifest::kInvalidOrMissingColor);
ASSERT_EQ(manifest.background_color, Manifest::kInvalidOrMissingColor);
ASSERT_TRUE(manifest.gcm_sender_id.is_null());
+ ASSERT_TRUE(manifest.scope.is_empty());
}
TEST_F(ManifestParserTest, MultipleErrorsReporting) {
@@ -253,6 +255,14 @@ TEST_F(ManifestParserTest, StartURLParseRules) {
errors()[0]);
}
+ // Don't parse if property isn't a valid URL.
+ {
+ Manifest manifest = ParseManifest("{ \"start_url\": \"http://www.google.ca:a\" }");
+ ASSERT_TRUE(manifest.start_url.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'start_url' ignored, URL is invalid.", errors()[0]);
+ }
+
// Absolute start_url, same origin with document.
{
Manifest manifest =
@@ -287,6 +297,151 @@ TEST_F(ManifestParserTest, StartURLParseRules) {
}
}
+TEST_F(ManifestParserTest, ScopeParseRules) {
+ // Smoke test.
+ {
+ Manifest manifest = ParseManifest(
+ "{ \"scope\": \"land\", \"start_url\": \"land/landing.html\" }");
+ ASSERT_EQ(manifest.scope.spec(),
+ default_document_url.Resolve("land").spec());
+ ASSERT_FALSE(manifest.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Whitespaces.
+ {
+ Manifest manifest = ParseManifest(
+ "{ \"scope\": \" land \", \"start_url\": \"land/landing.html\" }");
+ ASSERT_EQ(manifest.scope.spec(),
+ default_document_url.Resolve("land").spec());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse if property isn't a string.
+ {
+ Manifest manifest = ParseManifest("{ \"scope\": {} }");
+ ASSERT_TRUE(manifest.scope.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'scope' ignored, type string expected.", errors()[0]);
+ }
+
+ // Don't parse if property isn't a string.
+ {
+ Manifest manifest = ParseManifest("{ \"scope\": 42 }");
+ ASSERT_TRUE(manifest.scope.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'scope' ignored, type string expected.", errors()[0]);
+ }
+
+ // Absolute scope, start URL is in scope.
+ {
+ Manifest manifest = ParseManifestWithURLs(
+ "{ \"scope\": \"http://foo.com/land\", "
+ "\"start_url\": \"http://foo.com/land/landing.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(manifest.scope.spec(), "http://foo.com/land");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Absolute scope, start URL is not in scope.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"scope\": \"http://foo.com/land\", "
+ "\"start_url\": \"http://foo.com/index.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_TRUE(manifest.scope.is_empty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'scope' ignored. Start url should be within scope "
+ "of scope URL.",
+ errors()[0]);
+ }
+
+ // Absolute scope, start URL has different origin than scope URL.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"scope\": \"http://foo.com/land\", "
+ "\"start_url\": \"http://bar.com/land/landing.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_TRUE(manifest.scope.is_empty());
+ ASSERT_EQ(2u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'start_url' ignored, should be same origin as document.",
+ errors()[0]);
+ EXPECT_EQ("property 'scope' ignored. Start url should be within scope "
+ "of scope URL.",
+ errors()[1]);
+ }
+
+ // scope and start URL have diferent origin than document URL.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"scope\": \"http://foo.com/land\", "
+ "\"start_url\": \"http://foo.com/land/landing.html\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://bar.com/index.html"));
+ ASSERT_TRUE(manifest.scope.is_empty());
+ ASSERT_EQ(2u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'start_url' ignored, should be same origin as document.",
+ errors()[0]);
+ EXPECT_EQ("property 'scope' ignored, should be same origin as document.",
+ errors()[1]);
+ }
+
+ // No start URL. Document URL is in scope.
+ {
+ Manifest manifest = ParseManifestWithURLs("{ \"scope\": \"http://foo.com/land\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/land/index.html"));
+ ASSERT_EQ(manifest.scope.spec(), "http://foo.com/land");
+ ASSERT_EQ(0u, GetErrorCount());
+ }
+
+ // No start URL. Document is out of scope.
+ {
+ Manifest manifest = ParseManifestWithURLs("{ \"scope\": \"http://foo.com/land\" }",
+ GURL("http://foo.com/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'scope' ignored. Start url should be within scope "
+ "of scope URL.",
+ errors()[0]);
+ }
+
+ // Resolving has to happen based on the manifest_url.
+ {
+ Manifest manifest = ParseManifestWithURLs(
+ "{ \"scope\": \"treasure\" }",
+ GURL("http://foo.com/map/manifest.json"),
+ GURL("http://foo.com/map/treasure/island/index.html"));
+ ASSERT_EQ(manifest.scope.spec(), "http://foo.com/map/treasure");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Scope is parent directory.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"scope\": \"..\" }",
+ GURL("http://foo.com/map/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(manifest.scope.spec(), "http://foo.com/");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Scope tries to go up past domain.
+ {
+ Manifest manifest =
+ ParseManifestWithURLs("{ \"scope\": \"../..\" }",
+ GURL("http://foo.com/map/manifest.json"),
+ GURL("http://foo.com/index.html"));
+ ASSERT_EQ(manifest.scope.spec(), "http://foo.com/");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+}
+
TEST_F(ManifestParserTest, DisplayParserRules) {
// Smoke test.
{
@@ -512,7 +667,7 @@ TEST_F(ManifestParserTest, IconsParseRules) {
{
Manifest manifest = ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
EXPECT_EQ(manifest.icons.size(), 1u);
- EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/index.html");
+ EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/manifest.json");
EXPECT_FALSE(manifest.IsEmpty());
EXPECT_EQ(0u, GetErrorCount());
}
@@ -716,7 +871,6 @@ TEST_F(ManifestParserTest, IconSizesParseRules) {
{
Manifest manifest = ParseManifest("{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"x 40xx 1x2x3 x42 42xx42\" } ] }");
- gfx::Size any = gfx::Size(0, 0);
EXPECT_EQ(manifest.icons[0].sizes.size(), 0u);
EXPECT_EQ(1u, GetErrorCount());
EXPECT_EQ("found icon with no valid size.",
diff --git a/chromium/content/renderer/media/DEPS b/chromium/content/renderer/media/DEPS
index 29c1d241f42..37029086b55 100644
--- a/chromium/content/renderer/media/DEPS
+++ b/chromium/content/renderer/media/DEPS
@@ -1,7 +1,5 @@
include_rules = [
"+third_party/libvpx",
- # For video copying, cropping and scaling.
- # TODO(wuchengli): remove this when RTCVideoEncoder supports zero copy.
"+third_party/libyuv",
'+third_party/openh264/src/codec/api/svc',
'+third_party/opus',
diff --git a/chromium/content/renderer/media/android/media_info_loader_unittest.cc b/chromium/content/renderer/media/android/media_info_loader_unittest.cc
index 306ccdb50b8..3e0e1460410 100644
--- a/chromium/content/renderer/media/android/media_info_loader_unittest.cc
+++ b/chromium/content/renderer/media/android/media_info_loader_unittest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
#include "content/renderer/media/android/media_info_loader.h"
#include "content/test/mock_webframeclient.h"
#include "content/test/mock_weburlloader.h"
@@ -39,7 +40,7 @@ static const int kHttpNotFound = 404;
class MediaInfoLoaderTest : public testing::Test {
public:
MediaInfoLoaderTest()
- : view_(WebView::create(NULL)),
+ : view_(WebView::create(nullptr, blink::WebPageVisibilityStateVisible)),
frame_(WebLocalFrame::create(blink::WebTreeScopeType::Document,
&client_)) {
view_->setMainFrame(frame_);
@@ -84,7 +85,7 @@ class MediaInfoLoaderTest : public testing::Test {
loader_->willFollowRedirect(url_loader_, new_request, redirect_response);
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
void SendResponse(
diff --git a/chromium/content/renderer/media/android/renderer_media_player_manager.cc b/chromium/content/renderer/media/android/renderer_media_player_manager.cc
index a115772c0bc..b49a98e6563 100644
--- a/chromium/content/renderer/media/android/renderer_media_player_manager.cc
+++ b/chromium/content/renderer/media/android/renderer_media_player_manager.cc
@@ -281,6 +281,10 @@ media::RendererMediaPlayerInterface* RendererMediaPlayerManager::GetMediaPlayer(
return NULL;
}
+void RendererMediaPlayerManager::OnDestruct() {
+ delete this;
+}
+
#if defined(VIDEO_HOLE)
void RendererMediaPlayerManager::RequestExternalSurface(
int player_id,
diff --git a/chromium/content/renderer/media/android/renderer_media_player_manager.h b/chromium/content/renderer/media/android/renderer_media_player_manager.h
index 2baa846a0ad..9976488814d 100644
--- a/chromium/content/renderer/media/android/renderer_media_player_manager.h
+++ b/chromium/content/renderer/media/android/renderer_media_player_manager.h
@@ -116,6 +116,9 @@ class RendererMediaPlayerManager :
#endif // defined(VIDEO_HOLE)
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Message handlers.
void OnMediaMetadataChanged(int player_id,
base::TimeDelta duration,
diff --git a/chromium/content/renderer/media/android/renderer_media_session_manager.cc b/chromium/content/renderer/media/android/renderer_media_session_manager.cc
index 93d19281f94..b5331c7472a 100644
--- a/chromium/content/renderer/media/android/renderer_media_session_manager.cc
+++ b/chromium/content/renderer/media/android/renderer_media_session_manager.cc
@@ -33,6 +33,10 @@ bool RendererMediaSessionManager::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+void RendererMediaSessionManager::OnDestruct() {
+ delete this;
+}
+
int RendererMediaSessionManager::RegisterMediaSession(
WebMediaSessionAndroid* session) {
sessions_[next_session_id_] = session;
diff --git a/chromium/content/renderer/media/android/renderer_media_session_manager.h b/chromium/content/renderer/media/android/renderer_media_session_manager.h
index bc1808c3feb..fbfd5c848b0 100644
--- a/chromium/content/renderer/media/android/renderer_media_session_manager.h
+++ b/chromium/content/renderer/media/android/renderer_media_session_manager.h
@@ -44,6 +44,9 @@ class CONTENT_EXPORT RendererMediaSessionManager : public RenderFrameObserver {
private:
friend class WebMediaSessionTest;
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
std::map<int, WebMediaSessionAndroid*> sessions_;
int next_session_id_;
diff --git a/chromium/content/renderer/media/android/renderer_surface_view_manager.cc b/chromium/content/renderer/media/android/renderer_surface_view_manager.cc
index 6f54b1e30a1..48fd548c5ac 100644
--- a/chromium/content/renderer/media/android/renderer_surface_view_manager.cc
+++ b/chromium/content/renderer/media/android/renderer_surface_view_manager.cc
@@ -42,9 +42,14 @@ void RendererSurfaceViewManager::NaturalSizeChanged(const gfx::Size& size) {
void RendererSurfaceViewManager::OnFullscreenSurfaceCreated(int surface_id) {
DVLOG(3) << __FUNCTION__ << ": surface_id: " << surface_id;
- DCHECK(!pending_surface_created_cb_.is_null());
- pending_surface_created_cb_.Run(surface_id);
- pending_surface_created_cb_.Reset();
+ if (!pending_surface_created_cb_.is_null()) {
+ pending_surface_created_cb_.Run(surface_id);
+ pending_surface_created_cb_.Reset();
+ }
+}
+
+void RendererSurfaceViewManager::OnDestruct() {
+ delete this;
}
} // namespace content
diff --git a/chromium/content/renderer/media/android/renderer_surface_view_manager.h b/chromium/content/renderer/media/android/renderer_surface_view_manager.h
index 7022744bae1..f2918f37877 100644
--- a/chromium/content/renderer/media/android/renderer_surface_view_manager.h
+++ b/chromium/content/renderer/media/android/renderer_surface_view_manager.h
@@ -33,6 +33,9 @@ class CONTENT_EXPORT RendererSurfaceViewManager : public media::SurfaceManager,
void NaturalSizeChanged(const gfx::Size& size) override;
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
void OnFullscreenSurfaceCreated(int surface_id);
// Set when a surface request is in progress.
diff --git a/chromium/content/renderer/media/android/webmediaplayer_android.cc b/chromium/content/renderer/media/android/webmediaplayer_android.cc
index eab113b48d6..7adb15e764c 100644
--- a/chromium/content/renderer/media/android/webmediaplayer_android.cc
+++ b/chromium/content/renderer/media/android/webmediaplayer_android.cc
@@ -287,7 +287,8 @@ WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
// Part of |media_source_delegate_| needs to be stopped on the media thread.
// Wait until |media_source_delegate_| is fully stopped before tearing
// down other objects.
- base::WaitableEvent waiter(false, false);
+ base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
media_source_delegate_->Stop(
base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
waiter.Wait();
@@ -865,7 +866,7 @@ void WebMediaPlayerAndroid::OnPlaybackComplete() {
// If the loop attribute is set, timeChanged() will update the current time
// to 0. It will perform a seek to 0. Issue a command to the player to start
// playing after seek completes.
- if (seeking_ && seek_time_.is_zero())
+ if (is_playing_ && seeking_ && seek_time_.is_zero())
player_manager_->Start(player_id_);
else
playback_completed_ = true;
@@ -1513,11 +1514,6 @@ void WebMediaPlayerAndroid::OnWaitingForDecryptionKey() {
}
void WebMediaPlayerAndroid::OnHidden() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableMediaSuspend)) {
- return;
- }
-
OnSuspendRequested(false);
}
@@ -1527,6 +1523,12 @@ void WebMediaPlayerAndroid::OnShown() {
}
void WebMediaPlayerAndroid::OnSuspendRequested(bool must_suspend) {
+ if (!must_suspend &&
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableMediaSuspend)) {
+ return;
+ }
+
// If we're idle or playing video, pause and release resources; audio only
// players are allowed to continue unless indicated otherwise by the call.
if (must_suspend || (paused() && playback_completed_) || hasVideo())
diff --git a/chromium/content/renderer/media/audio_device_factory.cc b/chromium/content/renderer/media/audio_device_factory.cc
index a4b1d77c034..9f9b8c15962 100644
--- a/chromium/content/renderer/media/audio_device_factory.cc
+++ b/chromium/content/renderer/media/audio_device_factory.cc
@@ -15,7 +15,9 @@
#include "content/renderer/render_thread_impl.h"
#include "media/audio/audio_input_device.h"
#include "media/audio/audio_output_device.h"
+#include "media/base/audio_latency.h"
#include "media/base/audio_renderer_mixer_input.h"
+#include "media/base/media_switches.h"
#include "url/origin.h"
namespace content {
@@ -29,11 +31,31 @@ namespace {
// chance device authorization response is never received from the browser side.
// In this case we will time out, to avoid renderer hang forever waiting for
// device authorization (http://crbug/615589). This will result in "no audio".
-const int64_t kMaxAuthorizationTimeoutMs = 900;
+const int64_t kMaxAuthorizationTimeoutMs = 1000;
#else
const int64_t kMaxAuthorizationTimeoutMs = 0; // No timeout.
#endif // defined(OS_WIN)
+media::AudioLatency::LatencyType GetSourceLatencyType(
+ AudioDeviceFactory::SourceType source) {
+ switch (source) {
+ case AudioDeviceFactory::kSourceWebAudioInteractive:
+ return media::AudioLatency::LATENCY_INTERACTIVE;
+ case AudioDeviceFactory::kSourceNone:
+ case AudioDeviceFactory::kSourceWebRtc:
+ case AudioDeviceFactory::kSourceNonRtcAudioTrack:
+ case AudioDeviceFactory::kSourceWebAudioBalanced:
+ return media::AudioLatency::LATENCY_RTC;
+ case AudioDeviceFactory::kSourceMediaElement:
+ case AudioDeviceFactory::kSourceWebAudioPlayback:
+ return media::AudioLatency::LATENCY_PLAYBACK;
+ case AudioDeviceFactory::kSourceWebAudioExact:
+ return media::AudioLatency::LATENCY_EXACT_MS;
+ }
+ NOTREACHED();
+ return media::AudioLatency::LATENCY_INTERACTIVE;
+}
+
scoped_refptr<media::AudioOutputDevice> NewOutputDevice(
int render_frame_id,
int session_id,
@@ -57,12 +79,12 @@ bool IsMixable(AudioDeviceFactory::SourceType source_type) {
if (source_type == AudioDeviceFactory::kSourceMediaElement)
return true; // Must ALWAYS go through mixer.
- // TODO(olka): make a decision for the rest of the sources basing on OS
- // type and configuration parameters.
- return false;
+ // Mix everything if experiment is enabled; otherwise mix nothing else.
+ return base::FeatureList::IsEnabled(media::kNewAudioRenderingMixingStrategy);
}
scoped_refptr<media::SwitchableAudioRendererSink> NewMixableSink(
+ AudioDeviceFactory::SourceType source_type,
int render_frame_id,
int session_id,
const std::string& device_id,
@@ -70,7 +92,8 @@ scoped_refptr<media::SwitchableAudioRendererSink> NewMixableSink(
RenderThreadImpl* render_thread = RenderThreadImpl::current();
return scoped_refptr<media::AudioRendererMixerInput>(
render_thread->GetAudioRendererMixerManager()->CreateInput(
- render_frame_id, session_id, device_id, security_origin));
+ render_frame_id, session_id, device_id, security_origin,
+ GetSourceLatencyType(source_type)));
}
} // namespace
@@ -102,7 +125,7 @@ AudioDeviceFactory::NewAudioRendererSink(SourceType source_type,
}
if (IsMixable(source_type))
- return NewMixableSink(render_frame_id, session_id, device_id,
+ return NewMixableSink(source_type, render_frame_id, session_id, device_id,
security_origin);
return NewFinalAudioRendererSink(render_frame_id, session_id, device_id,
@@ -127,7 +150,7 @@ AudioDeviceFactory::NewSwitchableAudioRendererSink(
}
if (IsMixable(source_type))
- return NewMixableSink(render_frame_id, session_id, device_id,
+ return NewMixableSink(source_type, render_frame_id, session_id, device_id,
security_origin);
// AudioOutputDevice is not RestartableAudioRendererSink, so we can't return
@@ -152,22 +175,16 @@ AudioDeviceFactory::NewAudioCapturerSource(int render_frame_id) {
}
// static
-// TODO(http://crbug.com/587461): Find a better way to check if device exists
-// and is authorized.
media::OutputDeviceInfo AudioDeviceFactory::GetOutputDeviceInfo(
int render_frame_id,
int session_id,
const std::string& device_id,
const url::Origin& security_origin) {
- scoped_refptr<media::AudioRendererSink> sink = NewFinalAudioRendererSink(
+ RenderThreadImpl* render_thread = RenderThreadImpl::current();
+ DCHECK(render_thread) << "RenderThreadImpl is not instantiated, or "
+ << "GetOutputDeviceInfo() is called on a wrong thread ";
+ return render_thread->GetAudioRendererMixerManager()->GetOutputDeviceInfo(
render_frame_id, session_id, device_id, security_origin);
-
- const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo();
-
- // TODO(olka): Cache it and reuse, http://crbug.com/586161
- sink->Stop(); // Must be stopped.
-
- return device_info;
}
AudioDeviceFactory::AudioDeviceFactory() {
diff --git a/chromium/content/renderer/media/audio_device_factory.h b/chromium/content/renderer/media/audio_device_factory.h
index a8b8cb8b335..66936892b0b 100644
--- a/chromium/content/renderer/media/audio_device_factory.h
+++ b/chromium/content/renderer/media/audio_device_factory.h
@@ -32,14 +32,20 @@ namespace content {
// AudioCapturerSourceFactory.
class CONTENT_EXPORT AudioDeviceFactory {
public:
- // Types of audio sources.
+ // Types of audio sources. Each source can have individual mixing and/or
+ // latency requirements for output. The source is specified by the client when
+ // requesting output sink from the factory, and the factory creates the output
+ // sink basing on those requirements.
enum SourceType {
kSourceNone = 0,
kSourceMediaElement,
kSourceWebRtc,
kSourceNonRtcAudioTrack,
- kSourceWebAudio,
- kSourceLast = kSourceWebAudio // Only used for validation of format.
+ kSourceWebAudioInteractive,
+ kSourceWebAudioBalanced,
+ kSourceWebAudioPlayback,
+ kSourceWebAudioExact,
+ kSourceLast = kSourceWebAudioExact // Only used for validation of format.
};
// Creates a sink for AudioRendererMixer.
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager.cc b/chromium/content/renderer/media/audio_renderer_mixer_manager.cc
index 75b7ed60f30..30f66fb3771 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/chromium/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -4,20 +4,116 @@
#include "content/renderer/media/audio_renderer_mixer_manager.h"
+#include <algorithm>
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
#include "build/build_config.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio_renderer_sink_cache.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_hardware_config.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
+namespace {
+// Calculate mixer output parameters based on mixer input parameters and
+// hardware parameters for audio output.
+media::AudioParameters GetMixerOutputParams(
+ const media::AudioParameters& input_params,
+ const media::AudioParameters& hardware_params,
+ media::AudioLatency::LatencyType latency) {
+ int output_sample_rate = input_params.sample_rate();
+ bool valid_not_fake_hardware_params =
+ hardware_params.format() != media::AudioParameters::AUDIO_FAKE &&
+ hardware_params.IsValid();
+ int preferred_high_latency_output_buffer_size = 0;
+
+#if !defined(OS_CHROMEOS)
+ // On ChromeOS as well as when a fake device is used, we can rely on the
+ // playback device to handle resampling, so don't waste cycles on it here.
+ // On other systems if hardware parameters are valid and the device is not
+ // fake, resample to hardware sample rate. Otherwise, pass the input one and
+ // let the browser side handle automatic fallback.
+ if (valid_not_fake_hardware_params) {
+ output_sample_rate = hardware_params.sample_rate();
+ preferred_high_latency_output_buffer_size =
+ hardware_params.frames_per_buffer();
+ }
+#endif
+
+ int output_buffer_size = 0;
+
+ // Adjust output buffer size according to the latency requirement.
+ switch (latency) {
+ case media::AudioLatency::LATENCY_INTERACTIVE:
+ output_buffer_size = media::AudioLatency::GetInteractiveBufferSize(
+ hardware_params.frames_per_buffer());
+ break;
+ case media::AudioLatency::LATENCY_RTC:
+ output_buffer_size = media::AudioLatency::GetRtcBufferSize(
+ output_sample_rate, valid_not_fake_hardware_params
+ ? hardware_params.frames_per_buffer()
+ : 0);
+ break;
+ case media::AudioLatency::LATENCY_PLAYBACK:
+ output_buffer_size = media::AudioLatency::GetHighLatencyBufferSize(
+ output_sample_rate, preferred_high_latency_output_buffer_size);
+ break;
+ case media::AudioLatency::LATENCY_EXACT_MS:
+ // TODO(olka): add support when WebAudio requires it.
+ default:
+ NOTREACHED();
+ }
+
+ DCHECK_NE(output_buffer_size, 0);
+
+ // Force to 16-bit output for now since we know that works everywhere;
+ // ChromeOS does not support other bit depths.
+ return media::AudioParameters(input_params.format(),
+ input_params.channel_layout(),
+ output_sample_rate, 16, output_buffer_size);
+}
+
+void LogMixerUmaHistogram(media::AudioLatency::LatencyType latency, int value) {
+ switch (latency) {
+ case media::AudioLatency::LATENCY_EXACT_MS:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audio.Render.AudioInputsPerMixer.LatencyExact", value, 1, 20,
+ 21);
+ return;
+ case media::AudioLatency::LATENCY_INTERACTIVE:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audio.Render.AudioInputsPerMixer.LatencyInteractive", value, 1,
+ 20, 21);
+ return;
+ case media::AudioLatency::LATENCY_RTC:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audio.Render.AudioInputsPerMixer.LatencyRtc", value, 1, 20,
+ 21);
+ return;
+ case media::AudioLatency::LATENCY_PLAYBACK:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Media.Audio.Render.AudioInputsPerMixer.LatencyPlayback", value, 1,
+ 20, 21);
+ return;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace
+
namespace content {
-AudioRendererMixerManager::AudioRendererMixerManager() {}
+AudioRendererMixerManager::AudioRendererMixerManager(
+ std::unique_ptr<AudioRendererSinkCache> sink_cache)
+ : sink_cache_(std::move(sink_cache)) {
+ DCHECK(sink_cache_);
+}
AudioRendererMixerManager::~AudioRendererMixerManager() {
// References to AudioRendererMixers may be owned by garbage collected
@@ -25,122 +121,130 @@ AudioRendererMixerManager::~AudioRendererMixerManager() {
// |mixers_| may leak (i.e., may be non-empty at this time) as well.
}
+// static
+std::unique_ptr<AudioRendererMixerManager> AudioRendererMixerManager::Create() {
+ return base::WrapUnique(
+ new AudioRendererMixerManager(AudioRendererSinkCache::Create()));
+}
+
media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput(
int source_render_frame_id,
int session_id,
const std::string& device_id,
- const url::Origin& security_origin) {
- // base::Unretained() is safe since AudioRendererMixerManager lives on the
- // renderer thread and is destroyed on renderer thread destruction.
+ const url::Origin& security_origin,
+ media::AudioLatency::LatencyType latency) {
+ // AudioRendererMixerManager lives on the renderer thread and is destroyed on
+ // renderer thread destruction, so it's safe to pass its pointer to a mixer
+ // input.
return new media::AudioRendererMixerInput(
- base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this),
- source_render_frame_id),
- base::Bind(&AudioRendererMixerManager::RemoveMixer,
- base::Unretained(this), source_render_frame_id),
+ this, source_render_frame_id,
media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
device_id)
- ? AudioDeviceFactory::GetOutputDeviceInfo(
- source_render_frame_id, session_id, device_id, security_origin)
+ ? GetOutputDeviceInfo(source_render_frame_id, session_id, device_id,
+ security_origin)
.device_id()
: device_id,
- security_origin);
+ security_origin, latency);
}
media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
int source_render_frame_id,
- const media::AudioParameters& params,
+ const media::AudioParameters& input_params,
+ media::AudioLatency::LatencyType latency,
const std::string& device_id,
const url::Origin& security_origin,
media::OutputDeviceStatus* device_status) {
// Effects are not passed through to output creation, so ensure none are set.
- DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS);
+ DCHECK_EQ(input_params.effects(), media::AudioParameters::NO_EFFECTS);
- const MixerKey key(source_render_frame_id, params, device_id,
+ const MixerKey key(source_render_frame_id, input_params, latency, device_id,
security_origin);
base::AutoLock auto_lock(mixers_lock_);
+ // Update latency map when the mixer is requested, i.e. there is an attempt to
+ // mix and output audio with a given latency. This is opposite to
+ // CreateInput() which creates a sink which is probably never used for output.
+ if (!latency_map_[latency]) {
+ latency_map_[latency] = 1;
+ // Log the updated latency map. This can't be done once in the end of the
+ // renderer lifetime, because the destructor is usually not called. So,
+ // we'll have a sort of exponential scale here, with a smaller subset
+ // logged both on its own and as a part of any larger subset.
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Media.Audio.Render.AudioMixing.LatencyMap",
+ latency_map_.to_ulong());
+ }
+
AudioRendererMixerMap::iterator it = mixers_.find(key);
if (it != mixers_.end()) {
if (device_status)
*device_status = media::OUTPUT_DEVICE_STATUS_OK;
it->second.ref_count++;
+ DVLOG(1) << "Reusing mixer: " << it->second.mixer;
return it->second.mixer;
}
scoped_refptr<media::AudioRendererSink> sink =
- AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0,
- device_id, security_origin);
+ sink_cache_->GetSink(source_render_frame_id, device_id, security_origin);
const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo();
if (device_status)
*device_status = device_info.device_status();
if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) {
+ sink_cache_->ReleaseSink(sink.get());
sink->Stop();
return nullptr;
}
- // On ChromeOS as well as when a fake device is used, we can rely on the
- // playback device to handle resampling, so don't waste cycles on it here.
- int sample_rate = params.sample_rate();
- int buffer_size =
- media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0);
-
-#if !defined(OS_CHROMEOS)
- const media::AudioParameters& hardware_params = device_info.output_params();
-
- // If we have valid, non-fake hardware parameters, use them. Otherwise, pass
- // on the input params and let the browser side handle automatic fallback.
- if (hardware_params.format() != media::AudioParameters::AUDIO_FAKE &&
- hardware_params.IsValid()) {
- sample_rate = hardware_params.sample_rate();
- buffer_size = media::AudioHardwareConfig::GetHighLatencyBufferSize(
- sample_rate, hardware_params.frames_per_buffer());
- }
-#endif
-
- // Create output parameters based on the audio hardware configuration for
- // passing on to the output sink. Force to 16-bit output for now since we
- // know that works everywhere; ChromeOS does not support other bit depths.
- media::AudioParameters output_params(
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(),
- sample_rate, 16, buffer_size);
- DCHECK(output_params.IsValid());
-
- media::AudioRendererMixer* mixer =
- new media::AudioRendererMixer(output_params, sink);
- AudioRendererMixerReference mixer_reference = { mixer, 1 };
+ const media::AudioParameters& mixer_output_params =
+ GetMixerOutputParams(input_params, device_info.output_params(), latency);
+ media::AudioRendererMixer* mixer = new media::AudioRendererMixer(
+ mixer_output_params, sink, base::Bind(LogMixerUmaHistogram, latency));
+ AudioRendererMixerReference mixer_reference = {mixer, 1, sink.get()};
mixers_[key] = mixer_reference;
+ DVLOG(1) << __FUNCTION__ << " mixer: " << mixer << " latency: " << latency
+ << "\n input: " << input_params.AsHumanReadableString()
+ << "\noutput: " << mixer_output_params.AsHumanReadableString();
return mixer;
}
-void AudioRendererMixerManager::RemoveMixer(
- int source_render_frame_id,
- const media::AudioParameters& params,
- const std::string& device_id,
- const url::Origin& security_origin) {
- const MixerKey key(source_render_frame_id, params, device_id,
- security_origin);
+void AudioRendererMixerManager::ReturnMixer(media::AudioRendererMixer* mixer) {
base::AutoLock auto_lock(mixers_lock_);
-
- AudioRendererMixerMap::iterator it = mixers_.find(key);
+ AudioRendererMixerMap::iterator it = std::find_if(
+ mixers_.begin(), mixers_.end(),
+ [mixer](const std::pair<MixerKey, AudioRendererMixerReference>& val) {
+ return val.second.mixer == mixer;
+ });
DCHECK(it != mixers_.end());
// Only remove the mixer if AudioRendererMixerManager is the last owner.
it->second.ref_count--;
if (it->second.ref_count == 0) {
+ // The mixer will be deleted now, so release the sink.
+ sink_cache_->ReleaseSink(it->second.sink_ptr);
delete it->second.mixer;
mixers_.erase(it);
}
}
+media::OutputDeviceInfo AudioRendererMixerManager::GetOutputDeviceInfo(
+ int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) {
+ return sink_cache_->GetSinkInfo(source_render_frame_id, session_id, device_id,
+ security_origin);
+}
+
AudioRendererMixerManager::MixerKey::MixerKey(
int source_render_frame_id,
const media::AudioParameters& params,
+ media::AudioLatency::LatencyType latency,
const std::string& device_id,
const url::Origin& security_origin)
: source_render_frame_id(source_render_frame_id),
params(params),
+ latency(latency),
device_id(device_id),
security_origin(security_origin) {}
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager.h b/chromium/content/renderer/media/audio_renderer_mixer_manager.h
index 20a1aa59eaf..7d77212bbe6 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager.h
+++ b/chromium/content/renderer/media/audio_renderer_mixer_manager.h
@@ -5,31 +5,36 @@
#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_
#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_
+#include <bitset>
#include <map>
+#include <memory>
#include <string>
-#include <utility>
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "media/audio/audio_device_description.h"
+#include "media/base/audio_latency.h"
#include "media/base/audio_parameters.h"
+#include "media/base/audio_renderer_mixer_pool.h"
#include "media/base/output_device_info.h"
#include "url/origin.h"
namespace media {
-class AudioHardwareConfig;
class AudioRendererMixer;
class AudioRendererMixerInput;
class AudioRendererSink;
}
namespace content {
+class AudioRendererSinkCache;
// Manages sharing of an AudioRendererMixer among AudioRendererMixerInputs based
// on their AudioParameters configuration. Inputs with the same AudioParameters
// configuration will share a mixer while a new AudioRendererMixer will be
-// lazily created if one with the exact AudioParameters does not exist.
+// lazily created if one with the exact AudioParameters does not exist. When an
+// AudioRendererMixer is returned by AudioRendererMixerInput, it will be deleted
+// if its only other reference is held by AudioRendererMixerManager.
//
// There should only be one instance of AudioRendererMixerManager per render
// thread.
@@ -39,10 +44,12 @@ namespace content {
// with floats. However, bits per channel is currently used to interleave the
// audio data by AudioOutputDevice::AudioThreadCallback::Process for consumption
// via the shared memory. See http://crbug.com/114700.
-class CONTENT_EXPORT AudioRendererMixerManager {
+class CONTENT_EXPORT AudioRendererMixerManager
+ : public media::AudioRendererMixerPool {
public:
- AudioRendererMixerManager();
- ~AudioRendererMixerManager();
+ ~AudioRendererMixerManager() final;
+
+ static std::unique_ptr<AudioRendererMixerManager> Create();
// Creates an AudioRendererMixerInput with the proper callbacks necessary to
// retrieve an AudioRendererMixer instance from AudioRendererMixerManager.
@@ -56,23 +63,30 @@ class CONTENT_EXPORT AudioRendererMixerManager {
int source_render_frame_id,
int session_id,
const std::string& device_id,
- const url::Origin& security_origin);
-
- // Returns a mixer instance based on AudioParameters; an existing one if one
- // with the provided AudioParameters exists or a new one if not.
- media::AudioRendererMixer* GetMixer(int source_render_frame_id,
- const media::AudioParameters& params,
- const std::string& device_id,
- const url::Origin& security_origin,
- media::OutputDeviceStatus* device_status);
-
- // Remove a mixer instance given a mixer if the only other reference is held
- // by AudioRendererMixerManager. Every AudioRendererMixer owner must call
- // this method when it's done with a mixer.
- void RemoveMixer(int source_render_frame_id,
- const media::AudioParameters& params,
- const std::string& device_id,
- const url::Origin& security_origin);
+ const url::Origin& security_origin,
+ media::AudioLatency::LatencyType latency);
+
+ // AudioRendererMixerPool implementation.
+
+ media::AudioRendererMixer* GetMixer(
+ int source_render_frame_id,
+ const media::AudioParameters& input_params,
+ media::AudioLatency::LatencyType latency,
+ const std::string& device_id,
+ const url::Origin& security_origin,
+ media::OutputDeviceStatus* device_status) final;
+
+ void ReturnMixer(media::AudioRendererMixer* mixer) final;
+
+ media::OutputDeviceInfo GetOutputDeviceInfo(
+ int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) final;
+
+ protected:
+ explicit AudioRendererMixerManager(
+ std::unique_ptr<AudioRendererSinkCache> sink_cache);
private:
friend class AudioRendererMixerManagerTest;
@@ -82,11 +96,13 @@ class CONTENT_EXPORT AudioRendererMixerManager {
struct MixerKey {
MixerKey(int source_render_frame_id,
const media::AudioParameters& params,
+ media::AudioLatency::LatencyType latency,
const std::string& device_id,
const url::Origin& security_origin);
MixerKey(const MixerKey& other);
int source_render_frame_id;
media::AudioParameters params;
+ media::AudioLatency::LatencyType latency;
std::string device_id;
url::Origin security_origin;
};
@@ -100,6 +116,13 @@ class CONTENT_EXPORT AudioRendererMixerManager {
if (a.params.channels() != b.params.channels())
return a.params.channels() < b.params.channels();
+ if (a.latency != b.latency)
+ return a.latency < b.latency;
+
+ // TODO(olka) add buffer duration comparison for LATENCY_EXACT_MS when
+ // adding support for it.
+ DCHECK_NE(media::AudioLatency::LATENCY_EXACT_MS, a.latency);
+
// Ignore effects(), bits_per_sample(), format(), and frames_per_buffer(),
// these parameters do not affect mixer reuse. All AudioRendererMixer
// units disable FIFO, so frames_per_buffer() can be safely ignored.
@@ -127,14 +150,24 @@ class CONTENT_EXPORT AudioRendererMixerManager {
struct AudioRendererMixerReference {
media::AudioRendererMixer* mixer;
int ref_count;
+ // Mixer sink pointer, to remove a sink from cache upon mixer destruction.
+ const media::AudioRendererSink* sink_ptr;
};
- typedef std::map<MixerKey, AudioRendererMixerReference, MixerKeyCompare>
- AudioRendererMixerMap;
+
+ using AudioRendererMixerMap =
+ std::map<MixerKey, AudioRendererMixerReference, MixerKeyCompare>;
// Active mixers.
AudioRendererMixerMap mixers_;
base::Lock mixers_lock_;
+ // Mixer sink cache.
+ const std::unique_ptr<AudioRendererSinkCache> sink_cache_;
+
+ // Map of the output latencies encountered throughout mixer manager lifetime.
+ // Used for UMA histogram logging.
+ std::bitset<media::AudioLatency::LATENCY_COUNT> latency_map_;
+
DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManager);
};
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
index e3eb3b3718f..fbdb0c55076 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -6,12 +6,13 @@
#include <memory>
+#include "base/bind.h"
+#include "build/build_config.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio_renderer_sink_cache.h"
#include "media/audio/audio_device_description.h"
-#include "media/base/audio_capturer_source.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
@@ -23,56 +24,109 @@
namespace content {
-static const int kBitsPerChannel = 16;
-static const int kSampleRate = 48000;
-static const int kBufferSize = 8192;
-static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
-static const media::ChannelLayout kAnotherChannelLayout =
- media::CHANNEL_LAYOUT_2_1;
-static const char* const kDefaultDeviceId =
+namespace {
+const int kBitsPerChannel = 16;
+const int kSampleRate = 48000;
+const int kBufferSize = 8192;
+const int kHardwareSampleRate = 44100;
+const int kHardwareBufferSize = 128;
+const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
+const media::ChannelLayout kAnotherChannelLayout = media::CHANNEL_LAYOUT_2_1;
+const char* const kDefaultDeviceId =
media::AudioDeviceDescription::kDefaultDeviceId;
-static const char kAnotherDeviceId[] = "another-device-id";
-static const char kMatchedDeviceId[] = "matched-device-id";
-static const char kNonexistentDeviceId[] = "nonexistent-device-id";
+const char kAnotherDeviceId[] = "another-device-id";
+const char kMatchedDeviceId[] = "matched-device-id";
+const char kNonexistentDeviceId[] = "nonexistent-device-id";
-static const int kRenderFrameId = 124;
-static const int kAnotherRenderFrameId = 678;
+const int kRenderFrameId = 124;
+const int kAnotherRenderFrameId = 678;
+} // namespace;
using media::AudioParameters;
+using media::AudioLatency;
-class AudioRendererMixerManagerTest : public testing::Test,
- public AudioDeviceFactory {
+class FakeAudioRendererSinkCache : public AudioRendererSinkCache {
+ public:
+ using GetSinkCallback =
+ base::Callback<scoped_refptr<media::AudioRendererSink>(
+ int render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin)>;
+
+ using ReleaseSinkCallback =
+ base::Callback<void(const media::AudioRendererSink*)>;
+
+ FakeAudioRendererSinkCache(const GetSinkCallback& get_sink_cb,
+ const ReleaseSinkCallback& release_sink_cb)
+ : get_sink_cb_(get_sink_cb), release_sink_cb_(release_sink_cb) {}
+
+ media::OutputDeviceInfo GetSinkInfo(
+ int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) final {
+ return get_sink_cb_
+ .Run(source_render_frame_id, session_id, device_id, security_origin)
+ ->GetOutputDeviceInfo();
+ }
+
+ scoped_refptr<media::AudioRendererSink> GetSink(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) final {
+ return get_sink_cb_.Run(source_render_frame_id, 0, device_id,
+ security_origin);
+ }
+
+ void ReleaseSink(const media::AudioRendererSink* sink) final {
+ release_sink_cb_.Run(sink);
+ }
+
+ private:
+ GetSinkCallback get_sink_cb_;
+ ReleaseSinkCallback release_sink_cb_;
+};
+
+class AudioRendererMixerManagerTest : public testing::Test {
public:
AudioRendererMixerManagerTest()
- : manager_(new AudioRendererMixerManager()),
- mock_sink_(new media::MockAudioRendererSink()),
+ : manager_(new AudioRendererMixerManager(
+ std::unique_ptr<AudioRendererSinkCache>(
+ new FakeAudioRendererSinkCache(
+ base::Bind(&AudioRendererMixerManagerTest::GetSinkPtr,
+ base::Unretained(this)),
+ base::Bind(&AudioRendererMixerManagerTest::ReleaseSinkPtr,
+ base::Unretained(this)))))),
+ mock_sink_(new media::MockAudioRendererSink(
+ kDefaultDeviceId,
+ media::OUTPUT_DEVICE_STATUS_OK,
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout,
+ kHardwareSampleRate,
+ kBitsPerChannel,
+ kHardwareBufferSize))),
mock_sink_no_device_(new media::MockAudioRendererSink(
kNonexistentDeviceId,
media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)),
mock_sink_matched_device_(
new media::MockAudioRendererSink(kMatchedDeviceId,
media::OUTPUT_DEVICE_STATUS_OK)),
- mock_sink_for_session_id_(
- new media::MockAudioRendererSink(kMatchedDeviceId,
- media::OUTPUT_DEVICE_STATUS_OK)),
kSecurityOrigin2(GURL("http://localhost")) {}
media::AudioRendererMixer* GetMixer(
int source_render_frame_id,
const media::AudioParameters& params,
+ AudioLatency::LatencyType latency,
const std::string& device_id,
const url::Origin& security_origin,
media::OutputDeviceStatus* device_status) {
- return manager_->GetMixer(source_render_frame_id, params, device_id,
- security_origin, device_status);
+ return manager_->GetMixer(source_render_frame_id, params, latency,
+ device_id, security_origin, device_status);
}
- void RemoveMixer(int source_render_frame_id,
- const media::AudioParameters& params,
- const std::string& device_id,
- const url::Origin& security_origin) {
- return manager_->RemoveMixer(source_render_frame_id, params, device_id,
- security_origin);
+ void ReturnMixer(media::AudioRendererMixer* mixer) {
+ return manager_->ReturnMixer(mixer);
}
// Number of instantiated mixers.
@@ -81,24 +135,8 @@ class AudioRendererMixerManagerTest : public testing::Test,
}
protected:
- MOCK_METHOD1(CreateAudioCapturerSource,
- scoped_refptr<media::AudioCapturerSource>(int));
- MOCK_METHOD5(
- CreateSwitchableAudioRendererSink,
- scoped_refptr<media::SwitchableAudioRendererSink>(SourceType,
- int,
- int,
- const std::string&,
- const url::Origin&));
- MOCK_METHOD5(CreateAudioRendererSink,
- scoped_refptr<media::AudioRendererSink>(SourceType,
- int,
- int,
- const std::string&,
- const url::Origin&));
-
- scoped_refptr<media::AudioRendererSink> CreateFinalAudioRendererSink(
- int render_frame_id,
+ scoped_refptr<media::AudioRendererSink> GetSinkPtr(
+ int source_render_frame_id,
int session_id,
const std::string& device_id,
const url::Origin& security_origin) {
@@ -110,7 +148,7 @@ class AudioRendererMixerManagerTest : public testing::Test,
return mock_sink_no_device_;
if (device_id.empty()) {
// The sink used to get device ID from session ID if it's not empty
- return session_id ? mock_sink_for_session_id_ : mock_sink_;
+ return session_id ? mock_sink_matched_device_ : mock_sink_;
}
if (device_id == kMatchedDeviceId)
return mock_sink_matched_device_;
@@ -119,11 +157,13 @@ class AudioRendererMixerManagerTest : public testing::Test,
return nullptr;
}
+ MOCK_METHOD1(ReleaseSinkPtr, void(const media::AudioRendererSink*));
+
std::unique_ptr<AudioRendererMixerManager> manager_;
+
scoped_refptr<media::MockAudioRendererSink> mock_sink_;
scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_;
scoped_refptr<media::MockAudioRendererSink> mock_sink_matched_device_;
- scoped_refptr<media::MockAudioRendererSink> mock_sink_for_session_id_;
// To avoid global/static non-POD constants.
const url::Origin kSecurityOrigin;
@@ -133,50 +173,56 @@ class AudioRendererMixerManagerTest : public testing::Test,
DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest);
};
-// Verify GetMixer() and RemoveMixer() both work as expected; particularly with
+// Verify GetMixer() and ReturnMixer() both work as expected; particularly with
// respect to the explicit ref counting done.
-TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) {
+TEST_F(AudioRendererMixerManagerTest, GetReturnMixer) {
// Since we're testing two different sets of parameters, we expect
// AudioRendererMixerManager to call Start and Stop on our mock twice.
EXPECT_CALL(*mock_sink_.get(), Start()).Times(2);
EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2);
+ // We expect 2 mixers to be created; each of them should release the sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2);
+
// There should be no mixers outstanding to start with.
EXPECT_EQ(0, mixer_count());
- media::AudioParameters params1(
- AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate,
- kBitsPerChannel, kBufferSize);
+ media::AudioParameters params1(media::AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, kSampleRate, kBitsPerChannel,
+ kBufferSize);
- media::AudioRendererMixer* mixer1 = GetMixer(
- kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer1);
EXPECT_EQ(1, mixer_count());
// The same parameters should return the same mixer1.
- EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params1, kDefaultDeviceId,
- kSecurityOrigin, nullptr));
+ EXPECT_EQ(mixer1,
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr));
EXPECT_EQ(1, mixer_count());
- // Remove the extra mixer we just acquired.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return the extra mixer we just acquired.
+ ReturnMixer(mixer1);
EXPECT_EQ(1, mixer_count());
media::AudioParameters params2(
AudioParameters::AUDIO_PCM_LINEAR, kAnotherChannelLayout, kSampleRate * 2,
kBitsPerChannel, kBufferSize * 2);
- media::AudioRendererMixer* mixer2 = GetMixer(
- kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer2 =
+ GetMixer(kRenderFrameId, params2, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer2);
EXPECT_EQ(2, mixer_count());
// Different parameters should result in a different mixer1.
EXPECT_NE(mixer1, mixer2);
- // Remove both outstanding mixers.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return both outstanding mixers.
+ ReturnMixer(mixer1);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer2);
EXPECT_EQ(0, mixer_count());
}
@@ -187,13 +233,17 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) {
EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2);
EXPECT_EQ(mixer_count(), 0);
+ // We expect 2 mixers to be created; each of them should release the sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2);
+
media::AudioParameters params1(AudioParameters::AUDIO_PCM_LINEAR,
kChannelLayout,
kSampleRate,
kBitsPerChannel,
kBufferSize);
- media::AudioRendererMixer* mixer1 = GetMixer(
- kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params1, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer1);
EXPECT_EQ(1, mixer_count());
@@ -204,10 +254,12 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) {
kSampleRate * 2,
kBitsPerChannel * 2,
kBufferSize * 2);
- EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId,
- kSecurityOrigin, nullptr));
+ media::AudioRendererMixer* mixer2 =
+ GetMixer(kRenderFrameId, params2, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ EXPECT_EQ(mixer1, mixer2);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer2);
EXPECT_EQ(1, mixer_count());
// Modify some parameters that do matter: channel layout
@@ -217,28 +269,32 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) {
kBitsPerChannel,
kBufferSize);
ASSERT_NE(params3.channel_layout(), params1.channel_layout());
-
- EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId,
- kSecurityOrigin, nullptr));
+ media::AudioRendererMixer* mixer3 =
+ GetMixer(kRenderFrameId, params3, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ EXPECT_NE(mixer1, mixer3);
EXPECT_EQ(2, mixer_count());
- RemoveMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer3);
EXPECT_EQ(1, mixer_count());
- // Remove final mixer.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return final mixer.
+ ReturnMixer(mixer1);
EXPECT_EQ(0, mixer_count());
}
// Verify CreateInput() provides AudioRendererMixerInput with the appropriate
// callbacks and they are working as expected. Also, verify that separate
-// mixers are created for separate render views, even though the AudioParameters
-// are the same.
+// mixers are created for separate RenderFrames, even though the
+// AudioParameters are the same.
TEST_F(AudioRendererMixerManagerTest, CreateInput) {
// Expect AudioRendererMixerManager to call Start and Stop on our mock twice
// each. Note: Under normal conditions, each mixer would get its own sink!
EXPECT_CALL(*mock_sink_.get(), Start()).Times(2);
EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2);
+ // We expect 2 mixers to be created; each of them should release the sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2);
+
media::AudioParameters params(
AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate,
kBitsPerChannel, kBufferSize);
@@ -246,19 +302,20 @@ TEST_F(AudioRendererMixerManagerTest, CreateInput) {
// Create two mixer inputs and ensure this doesn't instantiate any mixers yet.
EXPECT_EQ(0, mixer_count());
media::FakeAudioRenderCallback callback(0);
- scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput(
- kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin));
+ scoped_refptr<media::AudioRendererMixerInput> input(
+ manager_->CreateInput(kRenderFrameId, 0, kDefaultDeviceId,
+ kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK));
input->Initialize(params, &callback);
EXPECT_EQ(0, mixer_count());
media::FakeAudioRenderCallback another_callback(1);
scoped_refptr<media::AudioRendererMixerInput> another_input(
manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId,
- kSecurityOrigin));
+ kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK));
another_input->Initialize(params, &another_callback);
EXPECT_EQ(0, mixer_count());
// Implicitly test that AudioRendererMixerInput was provided with the expected
- // callbacks needed to acquire an AudioRendererMixer and remove it.
+ // callbacks needed to acquire an AudioRendererMixer and return it.
input->Start();
EXPECT_EQ(1, mixer_count());
another_input->Start();
@@ -287,6 +344,10 @@ TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) {
EXPECT_CALL(*mock_sink_matched_device_.get(), Start()).Times(1);
EXPECT_CALL(*mock_sink_matched_device_.get(), Stop()).Times(1);
+ // We expect 3 mixers to be created; each of them should release a sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_matched_device_.get())).Times(1);
+
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
kChannelLayout, kSampleRate, kBitsPerChannel,
kBufferSize);
@@ -296,34 +357,37 @@ TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) {
// Empty device id, zero session id;
scoped_refptr<media::AudioRendererMixerInput> input_to_default_device(
manager_->CreateInput(kRenderFrameId, 0, // session_id
- std::string(), kSecurityOrigin));
+ std::string(), kSecurityOrigin,
+ AudioLatency::LATENCY_PLAYBACK));
input_to_default_device->Initialize(params, &callback);
EXPECT_EQ(0, mixer_count());
// Specific device id, zero session id;
scoped_refptr<media::AudioRendererMixerInput> input_to_matched_device(
manager_->CreateInput(kRenderFrameId, 0, // session_id
- kMatchedDeviceId, kSecurityOrigin));
+ kMatchedDeviceId, kSecurityOrigin,
+ AudioLatency::LATENCY_PLAYBACK));
input_to_matched_device->Initialize(params, &callback);
EXPECT_EQ(0, mixer_count());
// Specific device id, non-zero session id (to be ignored);
scoped_refptr<media::AudioRendererMixerInput> input_to_another_device(
manager_->CreateInput(kRenderFrameId, 1, // session id
- kAnotherDeviceId, kSecurityOrigin));
+ kAnotherDeviceId, kSecurityOrigin,
+ AudioLatency::LATENCY_PLAYBACK));
input_to_another_device->Initialize(params, &callback);
EXPECT_EQ(0, mixer_count());
// Empty device id, non-zero session id;
scoped_refptr<media::AudioRendererMixerInput>
- input_to_matched_device_with_session_id(
- manager_->CreateInput(kRenderFrameId, 2, // session id
- std::string(), kSecurityOrigin));
+ input_to_matched_device_with_session_id(manager_->CreateInput(
+ kRenderFrameId, 2, // session id
+ std::string(), kSecurityOrigin, AudioLatency::LATENCY_PLAYBACK));
input_to_matched_device_with_session_id->Initialize(params, &callback);
EXPECT_EQ(0, mixer_count());
// Implicitly test that AudioRendererMixerInput was provided with the expected
- // callbacks needed to acquire an AudioRendererMixer and remove it.
+ // callbacks needed to acquire an AudioRendererMixer and return it.
input_to_default_device->Start();
EXPECT_EQ(1, mixer_count());
@@ -359,32 +423,38 @@ TEST_F(AudioRendererMixerManagerTest, MixerDevices) {
EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3);
EXPECT_EQ(0, mixer_count());
+ // We expect 3 mixers to be created; each of them should release a sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(3);
+
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
kChannelLayout, kSampleRate, kBitsPerChannel,
kBufferSize);
- media::AudioRendererMixer* mixer1 = GetMixer(
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer1);
EXPECT_EQ(1, mixer_count());
- media::AudioRendererMixer* mixer2 = GetMixer(
- kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer2 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kAnotherDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer2);
EXPECT_EQ(2, mixer_count());
EXPECT_NE(mixer1, mixer2);
- media::AudioRendererMixer* mixer3 = GetMixer(
- kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2, nullptr);
+ media::AudioRendererMixer* mixer3 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kAnotherDeviceId, kSecurityOrigin2, nullptr);
ASSERT_TRUE(mixer3);
EXPECT_EQ(3, mixer_count());
EXPECT_NE(mixer1, mixer3);
EXPECT_NE(mixer2, mixer3);
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer1);
EXPECT_EQ(2, mixer_count());
- RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer2);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2);
+ ReturnMixer(mixer3);
EXPECT_EQ(0, mixer_count());
}
@@ -395,39 +465,46 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) {
EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
EXPECT_EQ(0, mixer_count());
+ // We expect 1 mixer to be created; it should release its sink.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
kChannelLayout, kSampleRate, kBitsPerChannel,
kBufferSize);
- media::AudioRendererMixer* mixer1 = GetMixer(
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer1);
EXPECT_EQ(1, mixer_count());
media::AudioRendererMixer* mixer2 =
- GetMixer(kRenderFrameId, params, std::string(), kSecurityOrigin, nullptr);
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ std::string(), kSecurityOrigin, nullptr);
ASSERT_TRUE(mixer2);
EXPECT_EQ(1, mixer_count());
EXPECT_EQ(mixer1, mixer2);
- media::AudioRendererMixer* mixer3 = GetMixer(
- kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr);
+ media::AudioRendererMixer* mixer3 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin2, nullptr);
ASSERT_TRUE(mixer3);
EXPECT_EQ(1, mixer_count());
EXPECT_EQ(mixer1, mixer3);
- media::AudioRendererMixer* mixer4 = GetMixer(
- kRenderFrameId, params, std::string(), kSecurityOrigin2, nullptr);
+ media::AudioRendererMixer* mixer4 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ std::string(), kSecurityOrigin2, nullptr);
ASSERT_TRUE(mixer4);
EXPECT_EQ(1, mixer_count());
EXPECT_EQ(mixer1, mixer4);
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(mixer1);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin);
+ ReturnMixer(mixer2);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2);
+ ReturnMixer(mixer3);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2);
+ ReturnMixer(mixer4);
EXPECT_EQ(0, mixer_count());
}
@@ -435,17 +512,320 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) {
// status code when a nonexistent device is requested.
TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) {
EXPECT_EQ(0, mixer_count());
+
+ // Mixer manager should release a not-ok sink when failing to create a mixer.
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_no_device_.get())).Times(1);
+
media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
kChannelLayout, kSampleRate, kBitsPerChannel,
kBufferSize);
media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK;
- EXPECT_CALL(*mock_sink_no_device_.get(), Stop());
+
media::AudioRendererMixer* mixer =
- GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin,
- &device_status);
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kNonexistentDeviceId, kSecurityOrigin, &device_status);
+
EXPECT_FALSE(mixer);
EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status);
EXPECT_EQ(0, mixer_count());
}
+// Verify GetMixer() correctly deduplicate mixers basing on latency
+// requirements.
+TEST_F(AudioRendererMixerManagerTest, LatencyMixing) {
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(3);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(3);
+
+ EXPECT_EQ(0, mixer_count());
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, kSampleRate, kBitsPerChannel,
+ kBufferSize);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ ASSERT_TRUE(mixer1);
+ EXPECT_EQ(1, mixer_count());
+
+ media::AudioRendererMixer* mixer2 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ ASSERT_TRUE(mixer2);
+ EXPECT_EQ(mixer1, mixer2); // Same latency => same mixer.
+ EXPECT_EQ(1, mixer_count());
+
+ media::AudioRendererMixer* mixer3 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_RTC,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ ASSERT_TRUE(mixer3);
+ EXPECT_NE(mixer1, mixer3);
+ EXPECT_EQ(2, mixer_count()); // Another latency => another mixer.
+
+ media::AudioRendererMixer* mixer4 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_RTC,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ EXPECT_EQ(mixer3, mixer4);
+ EXPECT_EQ(2, mixer_count()); // Same latency => same mixer.
+
+ media::AudioRendererMixer* mixer5 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_INTERACTIVE,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ ASSERT_TRUE(mixer5);
+ EXPECT_EQ(3, mixer_count()); // Another latency => another mixer.
+
+ media::AudioRendererMixer* mixer6 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_INTERACTIVE,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+ EXPECT_EQ(mixer5, mixer6);
+ EXPECT_EQ(3, mixer_count()); // Same latency => same mixer.
+
+ ReturnMixer(mixer1);
+ EXPECT_EQ(3, mixer_count());
+ ReturnMixer(mixer2);
+ EXPECT_EQ(2, mixer_count());
+ ReturnMixer(mixer3);
+ EXPECT_EQ(2, mixer_count());
+ ReturnMixer(mixer4);
+ EXPECT_EQ(1, mixer_count());
+ ReturnMixer(mixer5);
+ EXPECT_EQ(1, mixer_count());
+ ReturnMixer(mixer6);
+ EXPECT_EQ(0, mixer_count());
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for Playback
+// latency.
+TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyPlayback) {
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(44100,
+ mock_sink_->GetOutputDeviceInfo().output_params().sample_rate());
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(
+ 128,
+ mock_sink_->GetOutputDeviceInfo().output_params().frames_per_buffer());
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+#if defined(OS_CHROMEOS)
+ // Expecting input sample rate
+ EXPECT_EQ(32000, mixer->GetOutputParamsForTesting().sample_rate());
+ // Round up 20 ms (640) to the power of 2.
+ EXPECT_EQ(1024, mixer->GetOutputParamsForTesting().frames_per_buffer());
+
+#else
+ // Expecting hardware sample rate
+ EXPECT_EQ(44100, mixer->GetOutputParamsForTesting().sample_rate());
+
+// 20 ms at 44100 is 882 frames per buffer.
+#if defined(OS_WIN)
+ // Round up 882 to the nearest multiple of the output buffer size (128). which
+ // is 7 * 128 = 896
+ EXPECT_EQ(896, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#else
+ // Round up 882 to the power of 2.
+ EXPECT_EQ(1024, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#endif // defined(OS_WIN)
+
+#endif // defined(OS_CHROMEOS)
+
+ ReturnMixer(mixer);
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for Playback
+// latency when the device buffer size exceeds 20 ms.
+TEST_F(AudioRendererMixerManagerTest,
+ MixerParamsLatencyPlaybackLargeDeviceBufferSize) {
+ mock_sink_ = new media::MockAudioRendererSink(
+ std::string(), media::OUTPUT_DEVICE_STATUS_OK,
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 44100,
+ kBitsPerChannel, 2048));
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+// 20 ms at 44100 is 882 frames per buffer.
+#if defined(OS_CHROMEOS)
+ // Expecting input sample rate
+ EXPECT_EQ(32000, mixer->GetOutputParamsForTesting().sample_rate());
+ // Ignore device buffer size, round up 20 ms (640) to the power of 2.
+ EXPECT_EQ(1024, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#else
+ // Expecting hardware sample rate
+ EXPECT_EQ(44100, mixer->GetOutputParamsForTesting().sample_rate());
+ // Prefer device buffer size (2048) if is larger than 20 ms buffer size (882).
+ EXPECT_EQ(2048, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#endif
+
+ ReturnMixer(mixer);
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for Playback
+// latency when output audio is fake.
+TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyPlaybackFakeAudio) {
+ mock_sink_ = new media::MockAudioRendererSink(
+ std::string(), media::OUTPUT_DEVICE_STATUS_OK,
+ AudioParameters(AudioParameters::AUDIO_FAKE, kChannelLayout, 44100,
+ kBitsPerChannel, 2048));
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+ // Expecting input sample rate
+ EXPECT_EQ(32000, mixer->GetOutputParamsForTesting().sample_rate());
+
+// 20 ms at 32000 is 640 frames per buffer.
+#if defined(OS_WIN)
+ // Use 20 ms buffer.
+ EXPECT_EQ(640, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#else
+ // Ignore device buffer size, round up 640 to the power of 2.
+ EXPECT_EQ(1024, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#endif // defined(OS_WIN)
+
+ ReturnMixer(mixer);
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for RTC latency.
+TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyRtc) {
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(44100,
+ mock_sink_->GetOutputDeviceInfo().output_params().sample_rate());
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(
+ 128,
+ mock_sink_->GetOutputDeviceInfo().output_params().frames_per_buffer());
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_RTC,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+#if defined(OS_CHROMEOS)
+ int output_sample_rate = 32000;
+#else
+ // Expecting hardware sample rate.
+ int output_sample_rate = 44100;
+#endif // defined(OS_CHROMEOS)
+
+ EXPECT_EQ(output_sample_rate,
+ mixer->GetOutputParamsForTesting().sample_rate());
+
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+ // Use 10 ms buffer (441 frames per buffer).
+ EXPECT_EQ(output_sample_rate / 100,
+ mixer->GetOutputParamsForTesting().frames_per_buffer());
+#elif defined(OS_ANDROID)
+ // If hardware buffer size (128) is less than 20 ms (882), use 20 ms buffer
+ // (otherwise, use hardware buffer).
+ EXPECT_EQ(882, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#else
+ // Use hardware buffer size (128).
+ EXPECT_EQ(128, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#endif // defined(OS_LINUX) || defined(OS_MACOSX)
+
+ ReturnMixer(mixer);
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for RTC latency
+// when output audio is fake.
+TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyRtcFakeAudio) {
+ mock_sink_ = new media::MockAudioRendererSink(
+ std::string(), media::OUTPUT_DEVICE_STATUS_OK,
+ AudioParameters(AudioParameters::AUDIO_FAKE, kChannelLayout, 44100,
+ kBitsPerChannel, 128));
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_RTC,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+ // Expecting input sample rate.
+ EXPECT_EQ(32000, mixer->GetOutputParamsForTesting().sample_rate());
+
+ // 10 ms at 32000 is 320 frames per buffer. Expect it on all the platforms for
+ // fake audio output.
+ EXPECT_EQ(320, mixer->GetOutputParamsForTesting().frames_per_buffer());
+
+ ReturnMixer(mixer);
+}
+
+// Verify output bufer size of the mixer is correctly adjusted for Interactive
+// latency.
+TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyInteractive) {
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(44100,
+ mock_sink_->GetOutputDeviceInfo().output_params().sample_rate());
+ // Expecting hardware buffer size of 128 frames
+ EXPECT_EQ(
+ 128,
+ mock_sink_->GetOutputDeviceInfo().output_params().frames_per_buffer());
+
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(1);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1);
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, 32000, kBitsPerChannel, 512);
+
+ media::AudioRendererMixer* mixer =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_INTERACTIVE,
+ kDefaultDeviceId, kSecurityOrigin, nullptr);
+
+#if defined(OS_CHROMEOS)
+ // Expecting input sample rate.
+ EXPECT_EQ(32000, mixer->GetOutputParamsForTesting().sample_rate());
+#else
+ // Expecting hardware sample rate.
+ EXPECT_EQ(44100, mixer->GetOutputParamsForTesting().sample_rate());
+#endif // defined(OS_CHROMEOS)
+
+#if defined(OS_ANDROID)
+ // If hardware buffer size (128) is less than 1024, use 2048.
+ EXPECT_EQ(2048, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#else
+ // Expect hardware buffer size.
+ EXPECT_EQ(128, mixer->GetOutputParamsForTesting().frames_per_buffer());
+#endif
+
+ ReturnMixer(mixer);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache.h b/chromium/content/renderer/media/audio_renderer_sink_cache.h
new file mode 100644
index 00000000000..25ab762e8b2
--- /dev/null
+++ b/chromium/content/renderer/media/audio_renderer_sink_cache.h
@@ -0,0 +1,62 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
+
+#include <string>
+
+#include "content/common/content_export.h"
+#include "media/base/output_device_info.h"
+
+namespace url {
+class Origin;
+}
+
+namespace media {
+class AudioRendererSink;
+}
+
+namespace content {
+
+// Caches AudioRendererSink instances, provides them to the clients for usage,
+// tracks their used/unused state, reuses them to obtain output device
+// information, garbage-collects unused sinks.
+// Thread safe.
+class CONTENT_EXPORT AudioRendererSinkCache {
+ public:
+ virtual ~AudioRendererSinkCache() {}
+
+ // Creates default cache, to be used by AudioRendererMixerManager.
+ static std::unique_ptr<AudioRendererSinkCache> Create();
+
+ // Returns output device information for a specified sink.
+ virtual media::OutputDeviceInfo GetSinkInfo(
+ int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) = 0;
+
+ // Provides a sink for usage. The sink must be returned to the cache by
+ // calling ReleaseSink(). The sink must be stopped by the user before
+ // deletion, but after releasing it from the cache.
+ virtual scoped_refptr<media::AudioRendererSink> GetSink(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) = 0;
+
+ // Notifies the cache that the sink is not in use any more. Must be
+ // called by the client, so that the cache can garbage-collect the sink
+ // reference.
+ virtual void ReleaseSink(const media::AudioRendererSink* sink_ptr) = 0;
+
+ protected:
+ AudioRendererSinkCache() {}
+
+ DISALLOW_COPY_AND_ASSIGN(AudioRendererSinkCache);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc b/chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc
new file mode 100644
index 00000000000..9fef7d0937b
--- /dev/null
+++ b/chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc
@@ -0,0 +1,253 @@
+// 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 <algorithm>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/memory/ptr_util.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio_renderer_sink_cache_impl.h"
+#include "media/audio/audio_device_description.h"
+#include "media/base/audio_renderer_sink.h"
+#include "url/origin.h"
+
+namespace content {
+
+constexpr int kDeleteTimeoutMs = 5000;
+
+// Cached sink data.
+struct AudioRendererSinkCacheImpl::CacheEntry {
+ int source_render_frame_id;
+ std::string device_id;
+ url::Origin security_origin;
+ scoped_refptr<media::AudioRendererSink> sink; // Sink instance
+ bool used; // True if in use by a client.
+};
+
+// static
+std::unique_ptr<AudioRendererSinkCache> AudioRendererSinkCache::Create() {
+ return base::WrapUnique(new AudioRendererSinkCacheImpl(
+ base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AudioDeviceFactory::NewAudioRendererMixerSink),
+ base::TimeDelta::FromMilliseconds(kDeleteTimeoutMs)));
+}
+
+AudioRendererSinkCacheImpl::AudioRendererSinkCacheImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const CreateSinkCallback& create_sink_cb,
+ base::TimeDelta delete_timeout)
+ : task_runner_(std::move(task_runner)),
+ create_sink_cb_(create_sink_cb),
+ delete_timeout_(delete_timeout),
+ weak_ptr_factory_(this) {
+ weak_this_ = weak_ptr_factory_.GetWeakPtr();
+}
+
+AudioRendererSinkCacheImpl::~AudioRendererSinkCacheImpl() {
+ // We just release all the cached sinks here.
+}
+
+media::OutputDeviceInfo AudioRendererSinkCacheImpl::GetSinkInfo(
+ int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) {
+ CacheEntry cache_entry = {source_render_frame_id,
+ std::string() /* device_id */, security_origin,
+ nullptr /* sink */, false /* not used */};
+
+ if (media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
+ device_id)) {
+ // We are provided with session id instead of device id. Session id is
+ // unique, so we can't find any matching sink. Creating a new one.
+ cache_entry.sink = create_sink_cb_.Run(source_render_frame_id, session_id,
+ device_id, security_origin);
+ cache_entry.device_id = cache_entry.sink->GetOutputDeviceInfo().device_id();
+
+ DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get()
+ << " - used session to create new sink.";
+
+ // Cache a newly-created sink.
+ base::AutoLock auto_lock(cache_lock_);
+ cache_.push_back(cache_entry);
+
+ } else {
+ // Ignore session id.
+ base::AutoLock auto_lock(cache_lock_);
+
+ auto cache_iter =
+ FindCacheEntry_Locked(source_render_frame_id, device_id,
+ security_origin, false /* unused_only */);
+
+ if (cache_iter != cache_.end()) {
+ // A matching cached sink is found.
+ DVLOG(1) << "GetSinkInfo: address: " << cache_iter->sink.get()
+ << " - reused a cached sink.";
+
+ return cache_iter->sink->GetOutputDeviceInfo();
+ }
+
+ // No matching sink found, create a new one.
+ cache_entry.device_id = device_id;
+ cache_entry.sink = create_sink_cb_.Run(
+ source_render_frame_id, 0 /* session_id */, device_id, security_origin);
+
+ DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get()
+ << " - no matching cached sink found, created a new one.";
+
+ // Cache a newly-created sink.
+ cache_.push_back(cache_entry);
+ }
+
+ // Schedule it for deletion.
+ DeleteLaterIfUnused(cache_entry.sink.get());
+
+ DVLOG(1) << "GetSinkInfo: address: " << cache_entry.sink.get()
+ << " created. source_render_frame_id: " << source_render_frame_id
+ << " session_id: " << session_id << " device_id: " << device_id
+ << " security_origin: " << security_origin;
+
+ return cache_entry.sink->GetOutputDeviceInfo();
+}
+
+scoped_refptr<media::AudioRendererSink> AudioRendererSinkCacheImpl::GetSink(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) {
+ base::AutoLock auto_lock(cache_lock_);
+
+ auto cache_iter =
+ FindCacheEntry_Locked(source_render_frame_id, device_id, security_origin,
+ true /* unused_only */);
+
+ if (cache_iter != cache_.end()) {
+ // Found unused sink; mark it as used and return.
+ DVLOG(1) << "GetSink: address: " << cache_iter->sink.get()
+ << " - found unused cached sink, reusing it.";
+
+ cache_iter->used = true;
+ return cache_iter->sink;
+ }
+
+ // No unused sink is found, create one, mark it used, cache it and return.
+ CacheEntry cache_entry = {
+ source_render_frame_id, device_id, security_origin,
+ create_sink_cb_.Run(source_render_frame_id, 0 /* session_id */, device_id,
+ security_origin),
+ true /* used */};
+
+ cache_.push_back(cache_entry);
+
+ DVLOG(1) << "GetSink: address: " << cache_entry.sink.get()
+ << " - no unused cached sink found, created a new one."
+ << " source_render_frame_id: " << source_render_frame_id
+ << " device_id: " << device_id
+ << " security_origin: " << security_origin;
+ return cache_entry.sink;
+}
+
+void AudioRendererSinkCacheImpl::ReleaseSink(
+ const media::AudioRendererSink* sink_ptr) {
+ // We don't know the sink state, so won't reuse it. Delete it immediately.
+ DeleteSink(sink_ptr, true);
+}
+
+void AudioRendererSinkCacheImpl::DeleteLaterIfUnused(
+ const media::AudioRendererSink* sink_ptr) {
+ task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&AudioRendererSinkCacheImpl::DeleteSink, weak_this_,
+ sink_ptr, false /*do not delete if used*/),
+ delete_timeout_);
+}
+
+void AudioRendererSinkCacheImpl::DeleteSink(
+ const media::AudioRendererSink* sink_ptr,
+ bool force_delete_used) {
+ DCHECK(sink_ptr);
+
+ scoped_refptr<media::AudioRendererSink> sink_to_stop;
+
+ {
+ base::AutoLock auto_lock(cache_lock_);
+
+ // Looking up the sink by its pointer.
+ auto cache_iter = std::find_if(cache_.begin(), cache_.end(),
+ [sink_ptr](const CacheEntry& val) {
+ return val.sink.get() == sink_ptr;
+ });
+
+ if (cache_iter == cache_.end()) {
+ // If |force_delete_used| is not set it means the sink scheduled for
+ // deletion got aquired and released before scheduled deletion - it's ok.
+ DCHECK(!force_delete_used)
+ << "DeleteSink: address: " << sink_ptr
+ << " could not find a sink which is supposed to be in use";
+
+ DVLOG(1) << "DeleteSink: address: " << sink_ptr
+ << " force_delete_used = false - already deleted.";
+ return;
+ }
+
+ // When |force_delete_used| is set, it's expected that we are deleting a
+ // used sink.
+ DCHECK((!force_delete_used) || (force_delete_used && cache_iter->used))
+ << "Attempt to delete a non-aquired sink.";
+
+ if (!force_delete_used && cache_iter->used) {
+ DVLOG(1) << "DeleteSink: address: " << sink_ptr
+ << " sink in use, skipping deletion.";
+ return;
+ }
+
+ // To stop the sink before deletion if it's not used, we need to hold
+ // a ref to it.
+ if (!cache_iter->used)
+ sink_to_stop = cache_iter->sink;
+
+ cache_.erase(cache_iter);
+ DVLOG(1) << "DeleteSink: address: " << sink_ptr;
+ } // Lock scope;
+
+ // Stop the sink out of the lock scope.
+ if (sink_to_stop.get()) {
+ DCHECK_EQ(sink_ptr, sink_to_stop.get());
+ sink_to_stop->Stop();
+ DVLOG(1) << "DeleteSink: address: " << sink_ptr << " stopped.";
+ }
+}
+
+AudioRendererSinkCacheImpl::CacheContainer::iterator
+AudioRendererSinkCacheImpl::FindCacheEntry_Locked(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin,
+ bool unused_only) {
+ return std::find_if(
+ cache_.begin(), cache_.end(),
+ [source_render_frame_id, &device_id, &security_origin,
+ unused_only](const CacheEntry& val) {
+ if (val.used && unused_only)
+ return false;
+ if (val.source_render_frame_id != source_render_frame_id)
+ return false;
+ if (media::AudioDeviceDescription::IsDefaultDevice(device_id) &&
+ media::AudioDeviceDescription::IsDefaultDevice(val.device_id)) {
+ // Both device IDs represent the same default device => do not compare
+ // them; the default device is always authorized => ignore security
+ // origin.
+ return true;
+ }
+ return val.device_id == device_id &&
+ val.security_origin == security_origin;
+ });
+};
+
+int AudioRendererSinkCacheImpl::GetCacheSizeForTesting() {
+ return cache_.size();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.h b/chromium/content/renderer/media/audio_renderer_sink_cache_impl.h
new file mode 100644
index 00000000000..7d163d9074c
--- /dev/null
+++ b/chromium/content/renderer/media/audio_renderer_sink_cache_impl.h
@@ -0,0 +1,110 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
+
+#include "content/renderer/media/audio_renderer_sink_cache.h"
+
+#include <vector>
+
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// AudioRendererSinkCache implementation.
+class CONTENT_EXPORT AudioRendererSinkCacheImpl
+ : public AudioRendererSinkCache {
+ public:
+ // Callback to be used for AudioRendererSink creation
+ using CreateSinkCallback =
+ base::Callback<scoped_refptr<media::AudioRendererSink>(
+ int render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin)>;
+
+ AudioRendererSinkCacheImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const CreateSinkCallback& create_sink_callback,
+ base::TimeDelta delete_timeout);
+
+ ~AudioRendererSinkCacheImpl() final;
+
+ media::OutputDeviceInfo GetSinkInfo(int source_render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) final;
+
+ scoped_refptr<media::AudioRendererSink> GetSink(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) final;
+
+ void ReleaseSink(const media::AudioRendererSink* sink_ptr) final;
+
+ private:
+ friend class AudioRendererSinkCacheTest;
+ friend class CacheEntryFinder;
+
+ struct CacheEntry;
+ using CacheContainer = std::vector<CacheEntry>;
+
+ // Schedules a sink for deletion. Deletion will be performed on the same
+ // thread the cache is created on.
+ void DeleteLaterIfUnused(const media::AudioRendererSink* sink_ptr);
+
+ // Deletes a sink from the cache. If |force_delete_used| is set, a sink being
+ // deleted can (and should) be in use at the moment of deletion; otherwise the
+ // sink is deleted only if unused.
+ void DeleteSink(const media::AudioRendererSink* sink_ptr,
+ bool force_delete_used);
+
+ CacheContainer::iterator FindCacheEntry_Locked(
+ int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin,
+ bool unused_only);
+
+ // To avoid publishing CacheEntry structure in the header.
+ int GetCacheSizeForTesting();
+
+ // Task runner for scheduled sink garbage collection.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ // Callback used for sink creation.
+ const CreateSinkCallback create_sink_cb_;
+
+ // Cached sink deletion timeout.
+ // For example: (1) sink was created and cached in GetSinkInfo(), and then (2)
+ // the same sink is requested in GetSink(), if time interval between (1) and
+ // (2) is less than |kDeleteTimeoutMs|, then sink cached in (1) is reused in
+ // (2). On the other hand, if after (1) nobody is interested in the sink
+ // within |kDeleteTimeoutMs|, it is garbage-collected.
+ const base::TimeDelta delete_timeout_;
+
+ // Cached sinks, protected by lock.
+ base::Lock cache_lock_;
+ CacheContainer cache_;
+
+ // Weak pointer to be used for delayed sink deletion on |task_runner_|.
+ // Pre-created in constructor and is used to post all the delayed tasks.
+ // A delayed task can be concurrently posted from any thread the cache is used
+ // on, so on-the-flight weak pointer creation with
+ // weak_ptr_factory_.GetWeakPtr() can't be used, because it will result in the
+ // racy access to the factory.
+ base::WeakPtr<AudioRendererSinkCacheImpl> weak_this_;
+
+ // Used to produce |weak_this_| on AudioRendererSinkCacheImpl construction.
+ base::WeakPtrFactory<AudioRendererSinkCacheImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioRendererSinkCacheImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc b/chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc
new file mode 100644
index 00000000000..81e349c24fa
--- /dev/null
+++ b/chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc
@@ -0,0 +1,374 @@
+// 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 <array>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_timeouts.h"
+#include "content/renderer/media/audio_renderer_sink_cache_impl.h"
+#include "media/audio/audio_device_description.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/mock_audio_renderer_sink.h"
+#include "media/base/test_helpers.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+const char* const kDefaultDeviceId =
+ media::AudioDeviceDescription::kDefaultDeviceId;
+const char kAnotherDeviceId[] = "another-device-id";
+const int kRenderFrameId = 124;
+const int kDeleteTimeoutMs = 500;
+} // namespace
+
+class AudioRendererSinkCacheTest : public testing::Test {
+ public:
+ AudioRendererSinkCacheTest()
+ : cache_(new AudioRendererSinkCacheImpl(
+ message_loop_.task_runner(),
+ base::Bind(&AudioRendererSinkCacheTest::CreateSink,
+ base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(kDeleteTimeoutMs))) {}
+
+ void GetSink(int render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin,
+ media::AudioRendererSink** sink) {
+ *sink = cache_->GetSink(render_frame_id, device_id, security_origin).get();
+ }
+
+ void GetRandomSinkInfo(int frame) {
+ // Get info and check if memory is not corrupted.
+ EXPECT_EQ(kDefaultDeviceId,
+ cache_->GetSinkInfo(frame, 0, kDefaultDeviceId, url::Origin())
+ .device_id());
+ }
+
+ void GetRandomSink(int frame, base::TimeDelta sleep_timeout) {
+ scoped_refptr<media::AudioRendererSink> sink =
+ cache_->GetSink(frame, kDefaultDeviceId, url::Origin()).get();
+ ExpectToStop(sink.get());
+ base::PlatformThread::Sleep(sleep_timeout);
+ cache_->ReleaseSink(sink.get());
+ sink->Stop(); // Call a method to make the object is not corrupted.
+ }
+
+ protected:
+ int sink_count() {
+ DCHECK(message_loop_.task_runner()->BelongsToCurrentThread());
+ return cache_->GetCacheSizeForTesting();
+ }
+
+ scoped_refptr<media::AudioRendererSink> CreateSink(
+ int render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin) {
+ return new media::MockAudioRendererSink(device_id,
+ media::OUTPUT_DEVICE_STATUS_OK);
+ }
+
+ void ExpectToStop(media::AudioRendererSink* sink) {
+ // Sink must be stoped before deletion.
+ EXPECT_CALL(*static_cast<media::MockAudioRendererSink*>(sink), Stop())
+ .Times(1);
+ }
+
+ void ExpectNotToStop(media::AudioRendererSink* sink) {
+ // The sink must be stoped before deletion.
+ EXPECT_CALL(*static_cast<media::MockAudioRendererSink*>(sink), Stop())
+ .Times(0);
+ }
+
+ // Posts the task to the specified thread and runs current message loop until
+ // the task is completed.
+ void PostAndRunUntilDone(const base::Thread& thread,
+ const base::Closure& task) {
+ media::WaitableMessageLoopEvent event;
+ thread.task_runner()->PostTaskAndReply(FROM_HERE, task, event.GetClosure());
+ // Runs the loop and waits for the thread to call event's closure.
+ event.RunAndWait();
+ }
+
+ void WaitOnAnotherThread(const base::Thread& thread, int timeout_ms) {
+ PostAndRunUntilDone(
+ thread, base::Bind(base::IgnoreResult(&base::PlatformThread::Sleep),
+ base::TimeDelta::FromMilliseconds(timeout_ms)));
+ }
+
+ base::MessageLoop message_loop_;
+ std::unique_ptr<AudioRendererSinkCacheImpl> cache_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioRendererSinkCacheTest);
+};
+
+// Verify that normal get/release sink sequence works.
+TEST_F(AudioRendererSinkCacheTest, GetReleaseSink) {
+ // Verify that a new sink is successfully created.
+ EXPECT_EQ(0, sink_count());
+ scoped_refptr<media::AudioRendererSink> sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ ExpectNotToStop(sink.get()); // Cache should not stop sinks marked as used.
+ EXPECT_EQ(kDefaultDeviceId, sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(1, sink_count());
+
+ // Verify that another sink with the same key is successfully created
+ scoped_refptr<media::AudioRendererSink> another_sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ ExpectNotToStop(another_sink.get());
+ EXPECT_EQ(kDefaultDeviceId, another_sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(2, sink_count());
+ EXPECT_NE(sink, another_sink);
+
+ // Verify that another sink with a different kay is successfully created.
+ scoped_refptr<media::AudioRendererSink> yet_another_sink =
+ cache_->GetSink(kRenderFrameId, kAnotherDeviceId, url::Origin()).get();
+ ExpectNotToStop(yet_another_sink.get());
+ EXPECT_EQ(kAnotherDeviceId,
+ yet_another_sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(3, sink_count());
+ EXPECT_NE(sink, yet_another_sink);
+ EXPECT_NE(another_sink, yet_another_sink);
+
+ // Verify that the first sink is successfully deleted.
+ cache_->ReleaseSink(sink.get());
+ EXPECT_EQ(2, sink_count());
+ sink = nullptr;
+
+ // Make sure we deleted the right sink, and the memory for the rest is not
+ // corrupted.
+ EXPECT_EQ(kDefaultDeviceId, another_sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(kAnotherDeviceId,
+ yet_another_sink->GetOutputDeviceInfo().device_id());
+
+ // Verify that the second sink is successfully deleted.
+ cache_->ReleaseSink(another_sink.get());
+ EXPECT_EQ(1, sink_count());
+ EXPECT_EQ(kAnotherDeviceId,
+ yet_another_sink->GetOutputDeviceInfo().device_id());
+
+ cache_->ReleaseSink(yet_another_sink.get());
+ EXPECT_EQ(0, sink_count());
+}
+
+// Verify that the sink created with GetSinkInfo() is reused when possible.
+TEST_F(AudioRendererSinkCacheTest, GetDeviceInfo) {
+ EXPECT_EQ(0, sink_count());
+ media::OutputDeviceInfo device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count());
+
+ // The info on the same device is requested, so no new sink is created.
+ media::OutputDeviceInfo one_more_device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count());
+ EXPECT_EQ(device_info.device_id(), one_more_device_info.device_id());
+
+ // Aquire the sink that was created on GetSinkInfo().
+ scoped_refptr<media::AudioRendererSink> sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ EXPECT_EQ(1, sink_count());
+ EXPECT_EQ(device_info.device_id(), sink->GetOutputDeviceInfo().device_id());
+
+ // Now the sink is in used, but we can still get the device info out of it, no
+ // new sink is created.
+ one_more_device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count());
+ EXPECT_EQ(device_info.device_id(), one_more_device_info.device_id());
+
+ // Request sink for the same device. The first sink is in use, so a new one
+ // should be created.
+ scoped_refptr<media::AudioRendererSink> another_sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ EXPECT_EQ(2, sink_count());
+ EXPECT_EQ(device_info.device_id(),
+ another_sink->GetOutputDeviceInfo().device_id());
+}
+
+// Verify that the sink created with GetSinkInfo() is deleted if unused.
+// The test produces 2 "Uninteresting mock" warnings for
+// MockAudioRendererSink::Stop().
+TEST_F(AudioRendererSinkCacheTest, GarbageCollection) {
+ EXPECT_EQ(0, sink_count());
+ media::OutputDeviceInfo device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count());
+
+ media::OutputDeviceInfo another_device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kAnotherDeviceId, url::Origin());
+ EXPECT_EQ(2, sink_count());
+
+ base::Thread thread("timeout_thread");
+ thread.Start();
+
+ // 100 ms more than garbage collection timeout.
+ WaitOnAnotherThread(thread, kDeleteTimeoutMs + 100);
+
+ // All the sinks should be garbage-collected by now.
+ EXPECT_EQ(0, sink_count());
+}
+
+// Verify that the sink created with GetSinkInfo() is not deleted if used within
+// the timeout.
+TEST_F(AudioRendererSinkCacheTest, NoGarbageCollectionForUsedSink) {
+ EXPECT_EQ(0, sink_count());
+ media::OutputDeviceInfo device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count());
+
+ base::Thread thread("timeout_thread");
+ thread.Start();
+
+ // Wait significantly less than grabage collection timeout.
+ int wait_a_bit = 100;
+ DCHECK_GT(kDeleteTimeoutMs, wait_a_bit * 2);
+ WaitOnAnotherThread(thread, wait_a_bit);
+
+ // Sink is not deleted yet.
+ EXPECT_EQ(1, sink_count());
+
+ // Request it:
+ scoped_refptr<media::AudioRendererSink> sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ EXPECT_EQ(kDefaultDeviceId, sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(1, sink_count());
+
+ // Wait more to hit garbage collection timeout.
+ WaitOnAnotherThread(thread, kDeleteTimeoutMs);
+
+ // The sink is still in place.
+ EXPECT_EQ(1, sink_count());
+}
+
+// Verify that cache works fine if a sink scheduled for delettion is aquired and
+// released before deletion timeout elapses.
+// The test produces one "Uninteresting mock" warning for
+// MockAudioRendererSink::Stop().
+TEST_F(AudioRendererSinkCacheTest, ReleaseSinkBeforeScheduledDeletion) {
+ EXPECT_EQ(0, sink_count());
+
+ media::OutputDeviceInfo device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kDefaultDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count()); // This sink is scheduled for deletion now.
+
+ // Request it:
+ scoped_refptr<media::AudioRendererSink> sink =
+ cache_->GetSink(kRenderFrameId, kDefaultDeviceId, url::Origin()).get();
+ ExpectNotToStop(sink.get());
+ EXPECT_EQ(1, sink_count());
+
+ // Release it:
+ cache_->ReleaseSink(sink.get());
+ EXPECT_EQ(0, sink_count());
+
+ media::OutputDeviceInfo another_device_info =
+ cache_->GetSinkInfo(kRenderFrameId, 0, kAnotherDeviceId, url::Origin());
+ EXPECT_EQ(1, sink_count()); // This sink is scheduled for deletion now.
+
+ base::Thread thread("timeout_thread");
+ thread.Start();
+
+ // 100 ms more than garbage collection timeout.
+ WaitOnAnotherThread(thread, kDeleteTimeoutMs + 100);
+
+ // Nothing crashed and the second sink deleted on schedule.
+ EXPECT_EQ(0, sink_count());
+}
+
+// Check that a sink created on one thread in response to GetSinkInfo can be
+// used on another thread.
+TEST_F(AudioRendererSinkCacheTest, MultithreadedAccess) {
+ EXPECT_EQ(0, sink_count());
+
+ base::Thread thread1("thread1");
+ thread1.Start();
+
+ base::Thread thread2("thread2");
+ thread2.Start();
+
+ // Request device information on the first thread.
+ PostAndRunUntilDone(
+ thread1,
+ base::Bind(base::IgnoreResult(&AudioRendererSinkCacheImpl::GetSinkInfo),
+ base::Unretained(cache_.get()), kRenderFrameId, 0,
+ kDefaultDeviceId, url::Origin()));
+
+ EXPECT_EQ(1, sink_count());
+
+ // Request the sink on the second thread.
+ media::AudioRendererSink* sink;
+
+ PostAndRunUntilDone(
+ thread2,
+ base::Bind(&AudioRendererSinkCacheTest::GetSink, base::Unretained(this),
+ kRenderFrameId, kDefaultDeviceId, url::Origin(), &sink));
+
+ EXPECT_EQ(kDefaultDeviceId, sink->GetOutputDeviceInfo().device_id());
+ EXPECT_EQ(1, sink_count());
+
+ // Request device information on the first thread again.
+ PostAndRunUntilDone(
+ thread1,
+ base::Bind(base::IgnoreResult(&AudioRendererSinkCacheImpl::GetSinkInfo),
+ base::Unretained(cache_.get()), kRenderFrameId, 0,
+ kDefaultDeviceId, url::Origin()));
+ EXPECT_EQ(1, sink_count());
+
+ // Release the sink on the second thread.
+ PostAndRunUntilDone(thread2,
+ base::Bind(&AudioRendererSinkCache::ReleaseSink,
+ base::Unretained(cache_.get()), sink));
+
+ EXPECT_EQ(0, sink_count());
+}
+
+// Intensive parallell access to the cache. Produces a ton of "Uninteresting
+// mock" warnings for Stop() calls - this is fine.
+TEST_F(AudioRendererSinkCacheTest, SmokeTest) {
+ const int kExperimentSize = 1000;
+ const int kSinkCount = 10;
+ const int kThreadCount = 3;
+
+ // Sleep no more than (kDeleteTimeoutMs * 3) in total per thread.
+ const base::TimeDelta kSleepTimeout =
+ base::TimeDelta::FromMilliseconds(kDeleteTimeoutMs * 3 / kExperimentSize);
+
+ srand(42); // Does not matter.
+
+ std::array<std::unique_ptr<base::Thread>, kThreadCount> threads;
+ for (int i = 0; i < kThreadCount; ++i) {
+ threads[i].reset(new base::Thread(std::to_string(i)));
+ threads[i]->Start();
+ }
+
+ for (int i = 0; i < kExperimentSize; ++i) {
+ for (auto& thread : threads) {
+ thread->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&AudioRendererSinkCacheTest::GetRandomSinkInfo,
+ base::Unretained(this), rand() % kSinkCount));
+ thread->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&AudioRendererSinkCacheTest::GetRandomSink,
+ base::Unretained(this), rand() % kSinkCount,
+ kSleepTimeout));
+ }
+ }
+
+ // Wait for completion of all the tasks posted to at least one thread.
+ media::WaitableMessageLoopEvent loop_event(
+ TestTimeouts::action_max_timeout());
+ threads[kThreadCount - 1]->task_runner()->PostTaskAndReply(
+ FROM_HERE, base::Bind(&base::DoNothing), loop_event.GetClosure());
+ // Runs the loop and waits for the thread to call event's closure.
+ loop_event.RunAndWait();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/audio_track_recorder.cc b/chromium/content/renderer/media/audio_track_recorder.cc
index 603cbd99597..5d5e75235fa 100644
--- a/chromium/content/renderer/media/audio_track_recorder.cc
+++ b/chromium/content/renderer/media/audio_track_recorder.cc
@@ -15,6 +15,7 @@
#include "media/base/audio_converter.h"
#include "media/base/audio_fifo.h"
#include "media/base/audio_parameters.h"
+#include "media/base/audio_sample_types.h"
#include "media/base/bind_to_current_loop.h"
#include "third_party/opus/src/include/opus.h"
@@ -76,19 +77,6 @@ bool DoEncode(OpusEncoder* opus_encoder,
return false;
}
-// Interleaves |audio_bus| channels() of floats into a single output linear
-// |buffer|.
-// TODO(mcasas) https://crbug.com/580391 use AudioBus::ToInterleavedFloat().
-void ToInterleaved(media::AudioBus* audio_bus, float* buffer) {
- for (int ch = 0; ch < audio_bus->channels(); ++ch) {
- const float* src = audio_bus->channel(ch);
- const float* const src_end = src + audio_bus->frames();
- float* dest = buffer + ch;
- for (; src < src_end; ++src, dest += audio_bus->channels())
- *dest = *src;
- }
-}
-
} // anonymous namespace
// Nested class encapsulating opus-related encoding details. It contains an
@@ -119,7 +107,7 @@ class AudioTrackRecorder::AudioEncoder
// media::AudioConverted::InputCallback implementation.
double ProvideInput(media::AudioBus* audio_bus,
- base::TimeDelta buffer_delay) override;
+ uint32_t frames_delayed) override;
void DestroyExistingOpusEncoder();
@@ -259,7 +247,8 @@ void AudioTrackRecorder::AudioEncoder::EncodeAudio(
std::unique_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(
output_params_.channels(), kOpusPreferredFramesPerBuffer);
converter_->Convert(audio_bus.get());
- ToInterleaved(audio_bus.get(), buffer_.get());
+ audio_bus->ToInterleaved<media::Float32SampleTypeTraits>(
+ audio_bus->frames(), buffer_.get());
std::unique_ptr<std::string> encoded_data(new std::string());
if (DoEncode(opus_encoder_, buffer_.get(), kOpusPreferredFramesPerBuffer,
@@ -277,7 +266,7 @@ void AudioTrackRecorder::AudioEncoder::EncodeAudio(
double AudioTrackRecorder::AudioEncoder::ProvideInput(
media::AudioBus* audio_bus,
- base::TimeDelta buffer_delay) {
+ uint32_t frames_delayed) {
fifo_->Consume(audio_bus, 0, audio_bus->frames());
return 1.0; // Return volume greater than zero to indicate we have more data.
}
diff --git a/chromium/content/renderer/media/canvas_capture_handler.cc b/chromium/content/renderer/media/canvas_capture_handler.cc
index 91d67f7e5d6..11f9ed7d43c 100644
--- a/chromium/content/renderer/media/canvas_capture_handler.cc
+++ b/chromium/content/renderer/media/canvas_capture_handler.cc
@@ -20,6 +20,7 @@
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/libyuv/include/libyuv.h"
+#include "third_party/skia/include/core/SkImage.h"
namespace {
@@ -288,7 +289,7 @@ void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
web_track->initialize(webkit_source);
blink::WebMediaConstraints constraints;
constraints.initialize();
- web_track->setExtraData(new MediaStreamVideoTrack(
+ web_track->setTrackData(new MediaStreamVideoTrack(
media_stream_source.release(), constraints,
MediaStreamVideoSource::ConstraintsCallback(), true));
}
diff --git a/chromium/content/renderer/media/canvas_capture_handler.h b/chromium/content/renderer/media/canvas_capture_handler.h
index 4df1692223a..d4cd2568311 100644
--- a/chromium/content/renderer/media/canvas_capture_handler.h
+++ b/chromium/content/renderer/media/canvas_capture_handler.h
@@ -19,7 +19,9 @@
#include "third_party/WebKit/public/platform/WebCanvasCaptureHandler.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/WebKit/public/platform/WebSize.h"
-#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+
+class SkImage;
namespace content {
diff --git a/chromium/content/renderer/media/canvas_capture_handler_unittest.cc b/chromium/content/renderer/media/canvas_capture_handler_unittest.cc
index 98fe1c7d4fc..117fa8953a9 100644
--- a/chromium/content/renderer/media/canvas_capture_handler_unittest.cc
+++ b/chromium/content/renderer/media/canvas_capture_handler_unittest.cc
@@ -15,6 +15,8 @@
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/web/WebHeap.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
using ::testing::_;
using ::testing::InSequence;
diff --git a/chromium/content/renderer/media/cdm/renderer_cdm_manager.cc b/chromium/content/renderer/media/cdm/renderer_cdm_manager.cc
index 67402da7a84..4bf322a15fa 100644
--- a/chromium/content/renderer/media/cdm/renderer_cdm_manager.cc
+++ b/chromium/content/renderer/media/cdm/renderer_cdm_manager.cc
@@ -50,6 +50,10 @@ bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+void RendererCdmManager::OnDestruct() {
+ delete this;
+}
+
void RendererCdmManager::InitializeCdm(int cdm_id,
uint32_t promise_id,
ProxyMediaKeys* media_keys,
diff --git a/chromium/content/renderer/media/cdm/renderer_cdm_manager.h b/chromium/content/renderer/media/cdm/renderer_cdm_manager.h
index e25ce556d49..143d8035be4 100644
--- a/chromium/content/renderer/media/cdm/renderer_cdm_manager.h
+++ b/chromium/content/renderer/media/cdm/renderer_cdm_manager.h
@@ -74,6 +74,9 @@ class RendererCdmManager : public RenderFrameObserver {
void UnregisterMediaKeys(int cdm_id);
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Gets the pointer to ProxyMediaKeys given the |cdm_id|.
ProxyMediaKeys* GetMediaKeys(int cdm_id);
diff --git a/chromium/content/renderer/media/gpu/OWNERS b/chromium/content/renderer/media/gpu/OWNERS
new file mode 100644
index 00000000000..a1be1928a1c
--- /dev/null
+++ b/chromium/content/renderer/media/gpu/OWNERS
@@ -0,0 +1,2 @@
+posciak@chromium.org
+wuchengli@chromium.org
diff --git a/chromium/content/renderer/media/rtc_video_decoder.cc b/chromium/content/renderer/media/gpu/rtc_video_decoder.cc
index 32de1175114..1729882ab0d 100644
--- a/chromium/content/renderer/media/rtc_video_decoder.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_decoder.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/rtc_video_decoder.h"
+#include "content/renderer/media/gpu/rtc_video_decoder.h"
#include <utility>
@@ -67,6 +67,7 @@ RTCVideoDecoder::RTCVideoDecoder(webrtc::VideoCodecType type,
video_codec_type_(type),
factories_(factories),
decoder_texture_target_(0),
+ pixel_format_(media::PIXEL_FORMAT_UNKNOWN),
next_picture_buffer_id_(0),
state_(UNINITIALIZED),
decode_complete_callback_(nullptr),
@@ -120,7 +121,8 @@ std::unique_ptr<RTCVideoDecoder> RTCVideoDecoder::Create(
return decoder;
}
- base::WaitableEvent waiter(true, false);
+ base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
decoder.reset(new RTCVideoDecoder(type, factories));
decoder->factories_->GetTaskRunner()->PostTask(
FROM_HERE,
@@ -234,6 +236,10 @@ int32_t RTCVideoDecoder::Decode(
reset_bitstream_buffer_id_)) {
// TODO(wuchengli): VDA should handle it. Remove this when
// http://crosbug.com/p/21913 is fixed.
+
+ // If we're are in an error condition, increase the counter.
+ vda_error_counter_ += vda_error_counter_ ? 1 : 0;
+
DVLOG(1) << "The first frame should be a key frame. Drop this.";
return WEBRTC_VIDEO_CODEC_ERROR;
}
@@ -267,8 +273,6 @@ int32_t RTCVideoDecoder::Decode(
base::AutoUnlock auto_unlock(lock_);
Release();
}
-
- TryResetVDAErrorCounter_Locked();
return WEBRTC_VIDEO_CODEC_OK;
}
@@ -277,7 +281,6 @@ int32_t RTCVideoDecoder::Decode(
FROM_HERE,
base::Bind(&RTCVideoDecoder::RequestBufferDecode,
weak_factory_.GetWeakPtr()));
- TryResetVDAErrorCounter_Locked();
return WEBRTC_VIDEO_CODEC_OK;
}
@@ -315,6 +318,7 @@ int32_t RTCVideoDecoder::Release() {
}
void RTCVideoDecoder::ProvidePictureBuffers(uint32_t count,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& size,
uint32_t texture_target) {
@@ -328,6 +332,17 @@ void RTCVideoDecoder::ProvidePictureBuffers(uint32_t count,
std::vector<uint32_t> texture_ids;
std::vector<gpu::Mailbox> texture_mailboxes;
decoder_texture_target_ = texture_target;
+
+ if (format == media::PIXEL_FORMAT_UNKNOWN)
+ format = media::PIXEL_FORMAT_ARGB;
+
+ if ((pixel_format_ != media::PIXEL_FORMAT_UNKNOWN) &&
+ (format != pixel_format_)) {
+ NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
+ return;
+ }
+
+ pixel_format_ = format;
if (!factories_->CreateTextures(count,
size,
&texture_ids,
@@ -404,12 +419,8 @@ void RTCVideoDecoder::PictureReady(const media::Picture& picture) {
return;
}
- media::VideoPixelFormat pixel_format = vda_->GetOutputFormat();
- if (pixel_format == media::PIXEL_FORMAT_UNKNOWN)
- pixel_format = media::PIXEL_FORMAT_ARGB;
-
scoped_refptr<media::VideoFrame> frame =
- CreateVideoFrame(picture, pb, timestamp, visible_rect, pixel_format);
+ CreateVideoFrame(picture, pb, timestamp, visible_rect, pixel_format_);
if (!frame) {
NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
return;
@@ -433,6 +444,8 @@ void RTCVideoDecoder::PictureReady(const media::Picture& picture) {
reset_bitstream_buffer_id_)) {
decode_complete_callback_->Decoded(decoded_image);
}
+ // Reset error counter as we successfully decoded a frame.
+ vda_error_counter_ = 0;
}
}
@@ -879,12 +892,4 @@ void RTCVideoDecoder::ClearPendingBuffers() {
pending_buffers_.clear();
}
-void RTCVideoDecoder::TryResetVDAErrorCounter_Locked() {
- lock_.AssertAcquired();
-
- if (vda_error_counter_ == 0)
- return;
- vda_error_counter_ = 0;
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/rtc_video_decoder.h b/chromium/content/renderer/media/gpu/rtc_video_decoder.h
index 68d1c4baa76..274f6dfb6f6 100644
--- a/chromium/content/renderer/media/rtc_video_decoder.h
+++ b/chromium/content/renderer/media/gpu/rtc_video_decoder.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
-#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
+#ifndef CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_H_
+#define CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_H_
#include <stddef.h>
#include <stdint.h>
@@ -82,6 +82,7 @@ class CONTENT_EXPORT RTCVideoDecoder
// VideoDecodeAccelerator::Client implementation.
void ProvidePictureBuffers(uint32_t count,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& size,
uint32_t texture_target) override;
@@ -200,9 +201,6 @@ class CONTENT_EXPORT RTCVideoDecoder
// Clears the pending_buffers_ queue, freeing memory.
void ClearPendingBuffers();
- // Resets |vda_error_counter_| after a successfull run of decode.
- void TryResetVDAErrorCounter_Locked();
-
enum State {
UNINITIALIZED, // The decoder has not initialized.
INITIALIZED, // The decoder has initialized.
@@ -233,6 +231,9 @@ class CONTENT_EXPORT RTCVideoDecoder
// The texture target used for decoded pictures.
uint32_t decoder_texture_target_;
+ // The format of the decoded pictures.
+ media::VideoPixelFormat pixel_format_;
+
// Metadata of the buffers that have been sent for decode.
std::list<BufferData> input_buffer_data_;
@@ -302,4 +303,4 @@ class CONTENT_EXPORT RTCVideoDecoder
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_H_
+#endif // CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_H_
diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.cc b/chromium/content/renderer/media/gpu/rtc_video_decoder_factory.cc
index 0802698385e..04b9c1c648b 100644
--- a/chromium/content/renderer/media/rtc_video_decoder_factory.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_decoder_factory.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/rtc_video_decoder_factory.h"
+#include "content/renderer/media/gpu/rtc_video_decoder_factory.h"
#include <memory>
-#include "content/renderer/media/rtc_video_decoder.h"
+#include "content/renderer/media/gpu/rtc_video_decoder.h"
#include "media/renderers/gpu_video_accelerator_factories.h"
namespace content {
diff --git a/chromium/content/renderer/media/rtc_video_decoder_factory.h b/chromium/content/renderer/media/gpu/rtc_video_decoder_factory.h
index 7212b98bc78..5d53b2b125a 100644
--- a/chromium/content/renderer/media/rtc_video_decoder_factory.h
+++ b/chromium/content/renderer/media/gpu/rtc_video_decoder_factory.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_FACTORY_H_
#include "base/macros.h"
#include "base/threading/thread.h"
@@ -46,4 +46,4 @@ class CONTENT_EXPORT RTCVideoDecoderFactory
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_DECODER_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_DECODER_FACTORY_H_
diff --git a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc b/chromium/content/renderer/media/gpu/rtc_video_decoder_unittest.cc
index a3150048e8e..151e8fcb285 100644
--- a/chromium/content/renderer/media/rtc_video_decoder_unittest.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_decoder_unittest.cc
@@ -11,7 +11,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/media/rtc_video_decoder.h"
+#include "content/renderer/media/gpu/rtc_video_decoder.h"
#include "media/base/gmock_callback_support.h"
#include "media/renderers/mock_gpu_video_accelerator_factories.h"
#include "media/video/mock_video_decode_accelerator.h"
@@ -49,7 +49,8 @@ class RTCVideoDecoderTest
: mock_gpu_factories_(
new media::MockGpuVideoAcceleratorFactories(nullptr)),
vda_thread_("vda_thread"),
- idle_waiter_(false, false) {
+ idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED) {
memset(&codec_, 0, sizeof(codec_));
}
@@ -281,7 +282,8 @@ TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) {
rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST));
}
-
+// Tests/Verifies that |rtc_encoder_| drops incoming frames and its error
+// counter is increased when in an error condition.
TEST_P(RTCVideoDecoderTest, GetVDAErrorCounterForTesting) {
const webrtc::VideoCodecType codec_type = GetParam();
CreateDecoder(codec_type);
@@ -292,6 +294,7 @@ TEST_P(RTCVideoDecoderTest, GetVDAErrorCounterForTesting) {
input_image._encodedWidth = kMinResolutionWidth;
input_image._encodedHeight = kMaxResolutionHeight;
input_image._frameType = webrtc::kVideoFrameDelta;
+ input_image._length = kMinResolutionWidth * kMaxResolutionHeight;
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
rtc_decoder_->Decode(input_image, false, nullptr, nullptr, 0));
RunUntilIdle();
@@ -307,16 +310,11 @@ TEST_P(RTCVideoDecoderTest, GetVDAErrorCounterForTesting) {
rtc_decoder_->Decode(input_image, false, nullptr, nullptr, 0));
EXPECT_EQ(1, rtc_decoder_->GetVDAErrorCounterForTesting());
- // Decoder expects a keyframe after reset, so drops any other frames.
+ // Decoder expects a keyframe after reset, so drops any other frames. However,
+ // we should still increment the error counter.
EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
rtc_decoder_->Decode(input_image, false, nullptr, nullptr, 0));
- EXPECT_EQ(1, rtc_decoder_->GetVDAErrorCounterForTesting());
-
- // Decoder resets error counter after a successfull decode.
- input_image._frameType = webrtc::kVideoFrameKey;
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- rtc_decoder_->Decode(input_image, false, nullptr, nullptr, 10));
- EXPECT_EQ(0, rtc_decoder_->GetVDAErrorCounterForTesting());
+ EXPECT_EQ(2, rtc_decoder_->GetVDAErrorCounterForTesting());
}
INSTANTIATE_TEST_CASE_P(CodecProfiles,
diff --git a/chromium/content/renderer/media/rtc_video_encoder.cc b/chromium/content/renderer/media/gpu/rtc_video_encoder.cc
index 103e0c102b0..9cf55df82d3 100644
--- a/chromium/content/renderer/media/rtc_video_encoder.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/rtc_video_encoder.h"
+#include "content/renderer/media/gpu/rtc_video_encoder.h"
#include <string.h>
@@ -149,7 +149,8 @@ class RTCVideoEncoder::Impl
size_t output_buffer_size) override;
void BitstreamBufferReady(int32_t bitstream_buffer_id,
size_t payload_size,
- bool key_frame) override;
+ bool key_frame,
+ base::TimeDelta timestamp) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
private:
@@ -449,12 +450,13 @@ void RTCVideoEncoder::Impl::RequireBitstreamBuffers(
}
void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame) {
- DVLOG(3) << "Impl::BitstreamBufferReady(): "
- "bitstream_buffer_id=" << bitstream_buffer_id
- << ", payload_size=" << payload_size
- << ", key_frame=" << key_frame;
+ size_t payload_size,
+ bool key_frame,
+ base::TimeDelta timestamp) {
+ DVLOG(3) << "Impl::BitstreamBufferReady(): bitstream_buffer_id="
+ << bitstream_buffer_id << ", payload_size=" << payload_size
+ << ", key_frame=" << key_frame
+ << ", timestamp ms=" << timestamp.InMilliseconds();
DCHECK(thread_checker_.CalledOnValidThread());
if (bitstream_buffer_id < 0 ||
@@ -471,14 +473,17 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
}
output_buffers_free_count_--;
- // Use webrtc timestamps to ensure correct RTP sender behavior.
- // TODO(hshi): obtain timestamp from the capturer, see crbug.com/350106.
+ // CrOS Nyan provides invalid timestamp. Use the current time for now.
+ // TODO(wuchengli): use the timestamp in BitstreamBufferReady after Nyan is
+ // fixed. http://crbug.com/620565.
const int64_t capture_time_us = rtc::TimeMicros();
// Derive the capture time (in ms) and RTP timestamp (in 90KHz ticks).
- const int64_t capture_time_ms = capture_time_us / 1000;
- const uint32_t rtp_timestamp =
- static_cast<uint32_t>(capture_time_us * 90 / 1000);
+ const int64_t capture_time_ms =
+ capture_time_us / base::Time::kMicrosecondsPerMillisecond;
+
+ const uint32_t rtp_timestamp = static_cast<uint32_t>(
+ capture_time_us * 90 / base::Time::kMicrosecondsPerMillisecond);
webrtc::EncodedImage image(
reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size,
@@ -568,7 +573,7 @@ void RTCVideoEncoder::Impl::EncodeOneFrame() {
gfx::Rect(input_visible_size_), input_visible_size_,
reinterpret_cast<uint8_t*>(input_buffer->memory()),
input_buffer->mapped_size(), input_buffer->handle(), 0,
- base::TimeDelta());
+ base::TimeDelta::FromMilliseconds(next_frame->ntp_time_ms()));
if (!frame.get()) {
LogAndNotifyError(FROM_HERE, "failed to create frame",
media::VideoEncodeAccelerator::kPlatformFailureError);
@@ -740,7 +745,9 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
const media::VideoCodecProfile profile = WebRTCVideoCodecToVideoCodecProfile(
impl_->video_codec_type(), codec_settings);
- base::WaitableEvent initialization_waiter(true, false);
+ base::WaitableEvent initialization_waiter(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
int32_t initialization_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
gpu_task_runner_->PostTask(
FROM_HERE,
@@ -770,7 +777,9 @@ int32_t RTCVideoEncoder::Encode(
const bool want_key_frame = frame_types && frame_types->size() &&
frame_types->front() == webrtc::kVideoFrameKey;
- base::WaitableEvent encode_waiter(true, false);
+ base::WaitableEvent encode_waiter(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
int32_t encode_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
gpu_task_runner_->PostTask(
FROM_HERE,
@@ -795,7 +804,9 @@ int32_t RTCVideoEncoder::RegisterEncodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
- base::WaitableEvent register_waiter(true, false);
+ base::WaitableEvent register_waiter(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
int32_t register_retval = WEBRTC_VIDEO_CODEC_UNINITIALIZED;
gpu_task_runner_->PostTask(
FROM_HERE,
@@ -810,7 +821,9 @@ int32_t RTCVideoEncoder::Release() {
if (!impl_.get())
return WEBRTC_VIDEO_CODEC_OK;
- base::WaitableEvent release_waiter(true, false);
+ base::WaitableEvent release_waiter(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
gpu_task_runner_->PostTask(
FROM_HERE,
base::Bind(&RTCVideoEncoder::Impl::Destroy, impl_, &release_waiter));
diff --git a/chromium/content/renderer/media/rtc_video_encoder.h b/chromium/content/renderer/media/gpu/rtc_video_encoder.h
index c71c3baaf59..6f8053f3957 100644
--- a/chromium/content/renderer/media/rtc_video_encoder.h
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_
-#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_
+#ifndef CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_H_
+#define CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_H_
#include <stddef.h>
#include <stdint.h>
@@ -80,4 +80,4 @@ class CONTENT_EXPORT RTCVideoEncoder
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_H_
+#endif // CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_H_
diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.cc b/chromium/content/renderer/media/gpu/rtc_video_encoder_factory.cc
index 7e99b7c1386..9295464f758 100644
--- a/chromium/content/renderer/media/rtc_video_encoder_factory.cc
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder_factory.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/rtc_video_encoder_factory.h"
+#include "content/renderer/media/gpu/rtc_video_encoder_factory.h"
#include "base/command_line.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/feature_h264_with_openh264_ffmpeg.h"
-#include "content/renderer/media/rtc_video_encoder.h"
+#include "content/renderer/media/gpu/rtc_video_encoder.h"
#include "media/gpu/ipc/client/gpu_video_encode_accelerator_host.h"
#include "media/renderers/gpu_video_accelerator_factories.h"
#include "media/video/video_encode_accelerator.h"
diff --git a/chromium/content/renderer/media/rtc_video_encoder_factory.h b/chromium/content/renderer/media/gpu/rtc_video_encoder_factory.h
index 45b48ca82e1..efe538d33e8 100644
--- a/chromium/content/renderer/media/rtc_video_encoder_factory.h
+++ b/chromium/content/renderer/media/gpu/rtc_video_encoder_factory.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_FACTORY_H_
#include <vector>
@@ -45,4 +45,4 @@ class CONTENT_EXPORT RTCVideoEncoderFactory
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_RTC_VIDEO_ENCODER_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_GPU_RTC_VIDEO_ENCODER_FACTORY_H_
diff --git a/chromium/content/renderer/media/html_audio_element_capturer_source.cc b/chromium/content/renderer/media/html_audio_element_capturer_source.cc
new file mode 100644
index 00000000000..7e0edfc9768
--- /dev/null
+++ b/chromium/content/renderer/media/html_audio_element_capturer_source.cc
@@ -0,0 +1,90 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/html_audio_element_capturer_source.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/audio_renderer_sink.h"
+#include "media/blink/webaudiosourceprovider_impl.h"
+#include "media/blink/webmediaplayer_impl.h"
+#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
+
+namespace content {
+
+//static
+HtmlAudioElementCapturerSource*
+HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl(
+ blink::WebMediaPlayer* player) {
+ DCHECK(player);
+ return new HtmlAudioElementCapturerSource(
+ static_cast<media::WebAudioSourceProviderImpl*>(
+ player->getAudioSourceProvider()));
+}
+
+HtmlAudioElementCapturerSource::HtmlAudioElementCapturerSource(
+ media::WebAudioSourceProviderImpl* audio_source)
+ : MediaStreamAudioSource(true /* is_local_source */),
+ audio_source_(audio_source),
+ is_started_(false),
+ last_sample_rate_(0),
+ last_num_channels_(0),
+ last_bus_frames_(0) {
+ DCHECK(audio_source_);
+}
+
+HtmlAudioElementCapturerSource::~HtmlAudioElementCapturerSource() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ EnsureSourceIsStopped();
+}
+
+bool HtmlAudioElementCapturerSource::EnsureSourceIsStarted() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (audio_source_ && !is_started_) {
+ // base:Unretained() is safe here since EnsureSourceIsStopped() guarantees
+ // no more calls to OnAudioBus().
+ audio_source_->SetCopyAudioCallback(base::Bind(
+ &HtmlAudioElementCapturerSource::OnAudioBus, base::Unretained(this)));
+ is_started_ = true;
+ }
+ return is_started_;
+}
+
+void HtmlAudioElementCapturerSource::EnsureSourceIsStopped() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!is_started_)
+ return;
+
+ if (audio_source_) {
+ audio_source_->ClearCopyAudioCallback();
+ audio_source_ = nullptr;
+ }
+ is_started_ = false;
+}
+
+void HtmlAudioElementCapturerSource::OnAudioBus(
+ std::unique_ptr<media::AudioBus> audio_bus,
+ uint32_t frames_delayed,
+ int sample_rate) {
+ const base::TimeTicks capture_time =
+ base::TimeTicks::Now() -
+ base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond *
+ frames_delayed / sample_rate);
+
+ if (sample_rate != last_sample_rate_ ||
+ audio_bus->channels() != last_num_channels_ ||
+ audio_bus->frames() != last_bus_frames_) {
+ MediaStreamAudioSource::SetFormat(
+ media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ media::GuessChannelLayout(audio_bus->channels()),
+ sample_rate, 16, audio_bus->frames()));
+ last_sample_rate_ = sample_rate;
+ last_num_channels_ = audio_bus->channels();
+ last_bus_frames_ = audio_bus->frames();
+ }
+
+ MediaStreamAudioSource::DeliverDataToTracks(*audio_bus, capture_time);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/html_audio_element_capturer_source.h b/chromium/content/renderer/media/html_audio_element_capturer_source.h
new file mode 100644
index 00000000000..48ea5006832
--- /dev/null
+++ b/chromium/content/renderer/media/html_audio_element_capturer_source.h
@@ -0,0 +1,63 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_HTML_AUDIO_ELEMENT_CAPTURER_SOURCE_H_
+#define CONTENT_RENDERER_MEDIA_HTML_AUDIO_ELEMENT_CAPTURER_SOURCE_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+#include "content/renderer/media/media_stream_audio_source.h"
+
+namespace blink {
+class WebMediaPlayer;
+} // namespace blink
+
+namespace media {
+class AudioBus;
+class WebAudioSourceProviderImpl;
+} // namespace media
+
+namespace content {
+
+// This class is a MediaStreamAudioSource that registers to the constructor-
+// passed weak WebAudioSourceProviderImpl to receive a copy of the audio data
+// intended for rendering. This copied data is received on OnAudioBus() and sent
+// to all the registered Tracks.
+class CONTENT_EXPORT HtmlAudioElementCapturerSource final
+ : NON_EXPORTED_BASE(public MediaStreamAudioSource) {
+ public:
+ static HtmlAudioElementCapturerSource*
+ CreateFromWebMediaPlayerImpl(blink::WebMediaPlayer* player);
+
+ explicit HtmlAudioElementCapturerSource(
+ media::WebAudioSourceProviderImpl* audio_source);
+ ~HtmlAudioElementCapturerSource() override;
+
+ private:
+ // MediaStreamAudioSource implementation.
+ bool EnsureSourceIsStarted() final;
+ void EnsureSourceIsStopped() final;
+
+ // To act as an WebAudioSourceProviderImpl::CopyAudioCB.
+ void OnAudioBus(std::unique_ptr<media::AudioBus> audio_bus,
+ uint32_t frames_delayed,
+ int sample_rate);
+
+ scoped_refptr<media::WebAudioSourceProviderImpl> audio_source_;
+
+ bool is_started_;
+ int last_sample_rate_;
+ int last_num_channels_;
+ int last_bus_frames_;
+
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(HtmlAudioElementCapturerSource);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_HTML_AUDIO_ELEMENT_CAPTURER_SOURCE_H_
diff --git a/chromium/content/renderer/media/html_audio_element_capturer_source_unittest.cc b/chromium/content/renderer/media/html_audio_element_capturer_source_unittest.cc
new file mode 100644
index 00000000000..10d24ed7ec5
--- /dev/null
+++ b/chromium/content/renderer/media/html_audio_element_capturer_source_unittest.cc
@@ -0,0 +1,154 @@
+// 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 "base/memory/weak_ptr.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/renderer/media_stream_audio_sink.h"
+#include "content/renderer/media/html_audio_element_capturer_source.h"
+#include "content/renderer/media/media_stream_audio_track.h"
+#include "media/audio/null_audio_sink.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/fake_audio_render_callback.h"
+#include "media/blink/webaudiosourceprovider_impl.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebHeap.h"
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::InSequence;
+using ::testing::Mock;
+using ::testing::Property;
+
+namespace content {
+
+static const int kNumChannelsForTest = 1;
+static const int kBufferDurationMs = 10;
+
+static const int kAudioTrackSampleRate = 48000;
+static const int kAudioTrackSamplesPerBuffer =
+ kAudioTrackSampleRate * kBufferDurationMs /
+ base::Time::kMillisecondsPerSecond;
+
+ACTION_P(RunClosure, closure) {
+ closure.Run();
+}
+
+//
+class MockMediaStreamAudioSink final : public MediaStreamAudioSink {
+ public:
+ MockMediaStreamAudioSink() : MediaStreamAudioSink() {}
+ ~MockMediaStreamAudioSink() = default;
+
+ MOCK_METHOD1(OnSetFormat, void(const media::AudioParameters& params));
+ MOCK_METHOD2(OnData,
+ void(const media::AudioBus& audio_bus,
+ base::TimeTicks estimated_capture_time));
+
+ DISALLOW_COPY_AND_ASSIGN(MockMediaStreamAudioSink);
+};
+
+// This test needs to bundle together plenty of objects, namely:
+// - a WebAudioSourceProviderImpl, which in turn needs an Audio Sink, in this
+// case a NullAudioSink. This is needed to plug HTMLAudioElementCapturerSource
+// and inject audio.
+// - a WebMediaStreamSource, that owns the HTMLAudioElementCapturerSource under
+// test, and a WebMediaStreamAudioTrack, that the class under test needs to
+// connect to in order to operate correctly. This class has an inner content
+// MediaStreamAudioTrack.
+// - finally, a MockMediaStreamAudioSink to observe captured audio frames, and
+// that plugs into the former MediaStreamAudioTrack.
+class HTMLAudioElementCapturerSourceTest : public testing::Test {
+ public:
+ HTMLAudioElementCapturerSourceTest()
+ : fake_callback_(0.1),
+ audio_source_(new media::WebAudioSourceProviderImpl(
+ new media::NullAudioSink(base::ThreadTaskRunnerHandle::Get()))) {}
+
+ void SetUp() final {
+ const media::AudioParameters params(
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ media::GuessChannelLayout(kNumChannelsForTest),
+ kAudioTrackSampleRate /* sample_rate */, 16 /* bits_per_sample */,
+ kAudioTrackSamplesPerBuffer /* frames_per_buffer */);
+ audio_source_->Initialize(params, &fake_callback_);
+
+ blink_audio_source_.initialize(blink::WebString::fromUTF8("audio_id"),
+ blink::WebMediaStreamSource::TypeAudio,
+ blink::WebString::fromUTF8("audio_track"),
+ false /* remote */);
+ blink_audio_track_.initialize(blink_audio_source_.id(),
+ blink_audio_source_);
+
+ // |blink_audio_source_| takes ownership of HtmlAudioElementCapturerSource.
+ blink_audio_source_.setExtraData(
+ new HtmlAudioElementCapturerSource(audio_source_.get()));
+ ASSERT_TRUE(source()->ConnectToTrack(blink_audio_track_));
+ }
+
+ void TearDown() override {
+ blink_audio_track_.reset();
+ blink_audio_source_.reset();
+ blink::WebHeap::collectAllGarbageForTesting();
+ }
+
+ HtmlAudioElementCapturerSource* source() const {
+ return static_cast<HtmlAudioElementCapturerSource*>(
+ MediaStreamAudioSource::From(blink_audio_source_));
+ }
+
+ MediaStreamAudioTrack* track() const {
+ return MediaStreamAudioTrack::From(blink_audio_track_);
+ }
+
+ int InjectAudio(media::AudioBus* audio_bus) {
+ return audio_source_->RenderForTesting(audio_bus);
+ }
+
+ protected:
+ const base::MessageLoop message_loop_;
+
+ blink::WebMediaStreamSource blink_audio_source_;
+ blink::WebMediaStreamTrack blink_audio_track_;
+
+ media::FakeAudioRenderCallback fake_callback_;
+ scoped_refptr<media::WebAudioSourceProviderImpl> audio_source_;
+};
+
+// Constructs and destructs all objects. This is a non trivial sequence.
+TEST_F(HTMLAudioElementCapturerSourceTest, ConstructAndDestruct) {
+}
+
+// This test verifies that Audio can be properly captured when injected in the
+// WebAudioSourceProviderImpl.
+TEST_F(HTMLAudioElementCapturerSourceTest, CaptureAudio) {
+ InSequence s;
+
+ base::RunLoop run_loop;
+ base::Closure quit_closure = run_loop.QuitClosure();
+
+ MockMediaStreamAudioSink sink;
+ track()->AddSink(&sink);
+ EXPECT_CALL(sink, OnSetFormat(_)).Times(1);
+ EXPECT_CALL(
+ sink,
+ OnData(AllOf(Property(&media::AudioBus::channels, kNumChannelsForTest),
+ Property(&media::AudioBus::frames,
+ kAudioTrackSamplesPerBuffer)),
+ _))
+ .Times(1)
+ .WillOnce(RunClosure(quit_closure));
+
+ std::unique_ptr<media::AudioBus> bus = media::AudioBus::Create(
+ kNumChannelsForTest, kAudioTrackSamplesPerBuffer);
+ InjectAudio(bus.get());
+ run_loop.Run();
+
+ track()->Stop();
+ track()->RemoveSink(&sink);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/html_video_element_capturer_source.cc b/chromium/content/renderer/media/html_video_element_capturer_source.cc
index 3087a47aae2..88108ee50e5 100644
--- a/chromium/content/renderer/media/html_video_element_capturer_source.cc
+++ b/chromium/content/renderer/media/html_video_element_capturer_source.cc
@@ -4,7 +4,9 @@
#include "content/renderer/media/html_video_element_capturer_source.h"
+#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "content/public/renderer/render_thread.h"
@@ -12,11 +14,13 @@
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "media/base/limits.h"
#include "media/blink/webmediaplayer_impl.h"
+#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkXfermode.h"
namespace {
@@ -91,9 +95,12 @@ void HtmlVideoElementCapturerSource::StartCapture(
return;
}
const blink::WebSize resolution = web_media_player_->naturalSize();
- canvas_ = sk_sp<SkCanvas>(skia::CreatePlatformCanvas(resolution.width,
- resolution.height,
- true /* is_opaque */));
+ surface_ =
+ SkSurface::MakeRasterN32Premul(resolution.width, resolution.height);
+ if (!surface_) {
+ running_callback_.Run(false);
+ return;
+ }
new_frame_callback_ = new_frame_callback;
// Force |capture_frame_rate_| to be in between k{Min,Max}FramesPerSecond.
@@ -127,14 +134,15 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
const base::TimeTicks current_time = base::TimeTicks::Now();
const blink::WebSize resolution = web_media_player_->naturalSize();
+ SkCanvas* canvas = surface_->getCanvas();
web_media_player_->paint(
- canvas_.get(), blink::WebRect(0, 0, resolution.width, resolution.height),
+ canvas, blink::WebRect(0, 0, resolution.width, resolution.height),
0xFF /* alpha */, SkXfermode::kSrc_Mode);
- DCHECK_NE(kUnknown_SkColorType, canvas_->imageInfo().colorType());
- DCHECK_EQ(canvas_->imageInfo().width(), resolution.width);
- DCHECK_EQ(canvas_->imageInfo().height(), resolution.height);
+ DCHECK_NE(kUnknown_SkColorType, canvas->imageInfo().colorType());
+ DCHECK_EQ(canvas->imageInfo().width(), resolution.width);
+ DCHECK_EQ(canvas->imageInfo().height(), resolution.height);
- const SkBitmap bitmap = skia::ReadPixels(canvas_.get());
+ const SkBitmap bitmap = skia::ReadPixels(canvas);
DCHECK_NE(kUnknown_SkColorType, bitmap.colorType());
DCHECK(!bitmap.drawsNothing());
DCHECK(bitmap.getPixels());
@@ -160,8 +168,8 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
0 /* crop_y */,
bitmap.info().width(),
bitmap.info().height(),
- frame->natural_size().width(),
- frame->natural_size().height(),
+ frame->coded_size().width(),
+ frame->coded_size().height(),
libyuv::kRotate0,
libyuv::FOURCC_ARGB) == 0) {
// Success!
@@ -182,7 +190,7 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
next_capture_time_ = current_time;
}
// Schedule next capture.
- base::MessageLoop::current()->PostDelayedTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&HtmlVideoElementCapturerSource::sendNewFrame,
weak_factory_.GetWeakPtr()),
next_capture_time_ - current_time);
diff --git a/chromium/content/renderer/media/html_video_element_capturer_source.h b/chromium/content/renderer/media/html_video_element_capturer_source.h
index e248358846d..2d7598b5ece 100644
--- a/chromium/content/renderer/media/html_video_element_capturer_source.h
+++ b/chromium/content/renderer/media/html_video_element_capturer_source.h
@@ -13,14 +13,15 @@
#include "media/base/video_capturer_source.h"
#include "media/base/video_frame_pool.h"
#include "media/base/video_types.h"
-#include "skia/ext/platform_canvas.h"
-#include "skia/ext/refptr.h"
#include "third_party/WebKit/public/platform/WebSize.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
namespace blink {
class WebMediaPlayer;
} // namespace blink
+class SkSurface;
+
namespace content {
// This class is a VideoCapturerSource taking video snapshots of the ctor-passed
@@ -56,7 +57,7 @@ class CONTENT_EXPORT HtmlVideoElementCapturerSource final
void sendNewFrame();
media::VideoFramePool frame_pool_;
- sk_sp<SkCanvas> canvas_;
+ sk_sp<SkSurface> surface_;
const base::WeakPtr<blink::WebMediaPlayer> web_media_player_;
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
diff --git a/chromium/content/renderer/media/image_capture_frame_grabber.cc b/chromium/content/renderer/media/image_capture_frame_grabber.cc
index a7a37bf4d98..faeb43f8382 100644
--- a/chromium/content/renderer/media/image_capture_frame_grabber.cc
+++ b/chromium/content/renderer/media/image_capture_frame_grabber.cc
@@ -88,7 +88,7 @@ void ImageCaptureFrameGrabber::grabFrame(
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!!callbacks);
- DCHECK(track && !track->isNull() && track->getExtraData());
+ DCHECK(track && !track->isNull() && track->getTrackData());
DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track->source().getType());
ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> scoped_callbacks =
diff --git a/chromium/content/renderer/media/media_interface_provider.cc b/chromium/content/renderer/media/media_interface_provider.cc
index 84faca9bb32..8e3968e2182 100644
--- a/chromium/content/renderer/media/media_interface_provider.cc
+++ b/chromium/content/renderer/media/media_interface_provider.cc
@@ -37,6 +37,9 @@ void MediaInterfaceProvider::GetInterface(const mojo::String& interface_name,
} else if (interface_name == media::mojom::AudioDecoder::Name_) {
GetMediaServiceFactory()->CreateAudioDecoder(
mojo::MakeRequest<media::mojom::AudioDecoder>(std::move(pipe)));
+ } else if (interface_name == media::mojom::VideoDecoder::Name_) {
+ GetMediaServiceFactory()->CreateVideoDecoder(
+ mojo::MakeRequest<media::mojom::VideoDecoder>(std::move(pipe)));
} else {
NOTREACHED();
}
diff --git a/chromium/content/renderer/media/media_permission_dispatcher.cc b/chromium/content/renderer/media/media_permission_dispatcher.cc
index 764a4a0b92f..b28bc0363e1 100644
--- a/chromium/content/renderer/media/media_permission_dispatcher.cc
+++ b/chromium/content/renderer/media/media_permission_dispatcher.cc
@@ -9,6 +9,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/bind_to_current_loop.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "url/gurl.h"
namespace {
@@ -98,6 +99,7 @@ void MediaPermissionDispatcher::RequestPermission(
permission_service_->RequestPermission(
MediaPermissionTypeToPermissionName(type), security_origin.spec(),
+ blink::WebUserGestureIndicator::isProcessingUserGesture(),
base::Bind(&MediaPermissionDispatcher::OnPermissionStatus, weak_ptr_,
request_id));
}
diff --git a/chromium/content/renderer/media/media_recorder_handler.cc b/chromium/content/renderer/media/media_recorder_handler.cc
index 3dc54b51ef4..19cec5a4e92 100644
--- a/chromium/content/renderer/media/media_recorder_handler.cc
+++ b/chromium/content/renderer/media/media_recorder_handler.cc
@@ -40,10 +40,8 @@ media::VideoCodec CodecIdToMediaVideoCodec(VideoTrackRecorder::CodecId id) {
return media::kCodecVP8;
case VideoTrackRecorder::CodecId::VP9:
return media::kCodecVP9;
-#if BUILDFLAG(RTC_USE_H264)
case VideoTrackRecorder::CodecId::H264:
return media::kCodecH264;
-#endif
}
NOTREACHED() << "Unsupported codec";
return media::kUnknownVideoCodec;
@@ -177,6 +175,11 @@ bool MediaRecorderHandler::start(int timeslice) {
audio_tracks[0].source().getReadyState() !=
blink::WebMediaStreamSource::ReadyStateEnded;
+ if (!use_video_tracks && !use_audio_tracks) {
+ LOG(WARNING) << __FUNCTION__ << ": no tracks to be recorded.";
+ return false;
+ }
+
webm_muxer_.reset(new media::WebmMuxer(
CodecIdToMediaVideoCodec(codec_id_), use_video_tracks, use_audio_tracks,
base::Bind(&MediaRecorderHandler::WriteData,
diff --git a/chromium/content/renderer/media/media_stream_audio_deliverer.h b/chromium/content/renderer/media/media_stream_audio_deliverer.h
index 80a6a1c4193..cb0774eed54 100644
--- a/chromium/content/renderer/media/media_stream_audio_deliverer.h
+++ b/chromium/content/renderer/media/media_stream_audio_deliverer.h
@@ -137,7 +137,7 @@ class MediaStreamAudioDeliverer {
// |consumers_| on the audio thread.
std::vector<Consumer*> pending_consumers_;
- // Consumers that are up-to-date on the current audio format and are receiving
+ // Consumers that are up to date on the current audio format and are receiving
// audio data are placed in this list.
std::vector<Consumer*> consumers_;
diff --git a/chromium/content/renderer/media/media_stream_audio_processor.cc b/chromium/content/renderer/media/media_stream_audio_processor.cc
index 68aefcbff88..c02696e0684 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor.cc
+++ b/chromium/content/renderer/media/media_stream_audio_processor.cc
@@ -136,6 +136,11 @@ class MediaStreamAudioBus {
thread_checker_.DetachFromThread();
}
+ void ReattachThreadChecker() {
+ thread_checker_.DetachFromThread();
+ DCHECK(thread_checker_.CalledOnValidThread());
+ }
+
media::AudioBus* bus() {
DCHECK(thread_checker_.CalledOnValidThread());
return bus_.get();
@@ -194,6 +199,12 @@ class MediaStreamAudioFifo {
thread_checker_.DetachFromThread();
}
+ void ReattachThreadChecker() {
+ thread_checker_.DetachFromThread();
+ DCHECK(thread_checker_.CalledOnValidThread());
+ destination_->ReattachThreadChecker();
+ }
+
void Push(const media::AudioBus& source, base::TimeDelta audio_delay) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_EQ(source.channels(), source_channels_);
@@ -276,6 +287,7 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor(
WebRtcPlayoutDataSource* playout_data_source)
: render_delay_ms_(0),
playout_data_source_(playout_data_source),
+ main_thread_message_loop_(base::MessageLoop::current()),
audio_mirroring_(false),
typing_detected_(false),
stopped_(false) {
@@ -378,6 +390,7 @@ bool MediaStreamAudioProcessor::ProcessAndConsumeData(
void MediaStreamAudioProcessor::Stop() {
DCHECK(main_thread_checker_.CalledOnValidThread());
+
if (stopped_)
return;
@@ -398,6 +411,9 @@ void MediaStreamAudioProcessor::Stop() {
playout_data_source_->RemovePlayoutSink(this);
playout_data_source_ = NULL;
}
+
+ if (echo_information_)
+ echo_information_->ReportAndResetAecDivergentFilterStats();
}
const media::AudioParameters& MediaStreamAudioProcessor::InputFormat() const {
@@ -474,6 +490,12 @@ void MediaStreamAudioProcessor::OnPlayoutDataSourceChanged() {
render_fifo_.reset();
}
+void MediaStreamAudioProcessor::OnRenderThreadChanged() {
+ render_thread_checker_.DetachFromThread();
+ DCHECK(render_thread_checker_.CalledOnValidThread());
+ render_fifo_->ReattachThreadChecker();
+}
+
void MediaStreamAudioProcessor::GetStats(AudioProcessorStats* stats) {
stats->typing_noise_detected =
(base::subtle::Acquire_Load(&typing_detected_) != false);
@@ -739,13 +761,18 @@ int MediaStreamAudioProcessor::ProcessData(const float* const* process_ptrs,
base::subtle::Release_Store(&typing_detected_, detected);
}
- if (echo_information_) {
- echo_information_.get()->UpdateAecDelayStats(ap->echo_cancellation());
- }
+ main_thread_message_loop_->PostTask(
+ FROM_HERE, base::Bind(&MediaStreamAudioProcessor::UpdateAecStats, this));
// Return 0 if the volume hasn't been changed, and otherwise the new volume.
return (agc->stream_analog_level() == volume) ?
0 : agc->stream_analog_level();
}
+void MediaStreamAudioProcessor::UpdateAecStats() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ if (echo_information_)
+ echo_information_->UpdateAecStats(audio_processing_->echo_cancellation());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_audio_processor.h b/chromium/content/renderer/media/media_stream_audio_processor.h
index 66290159ce2..8b0c0943a46 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor.h
+++ b/chromium/content/renderer/media/media_stream_audio_processor.h
@@ -124,6 +124,7 @@ class CONTENT_EXPORT MediaStreamAudioProcessor :
int sample_rate,
int audio_delay_milliseconds) override;
void OnPlayoutDataSourceChanged() override;
+ void OnRenderThreadChanged() override;
// webrtc::AudioProcessorInterface implementation.
// This method is called on the libjingle thread.
@@ -152,6 +153,9 @@ class CONTENT_EXPORT MediaStreamAudioProcessor :
bool key_pressed,
float* const* output_ptrs);
+ // Update AEC stats. Called on the main render thread.
+ void UpdateAecStats();
+
// Cached value for the render delay latency. This member is accessed by
// both the capture audio thread and the render audio thread.
base::subtle::Atomic32 render_delay_ms_;
@@ -189,13 +193,17 @@ class CONTENT_EXPORT MediaStreamAudioProcessor :
// Used to DCHECK that some methods are called on the render audio thread.
base::ThreadChecker render_thread_checker_;
+ // Message loop for the main render thread. We're assuming that we're created
+ // on the main render thread.
+ base::MessageLoop* main_thread_message_loop_;
+
// Flag to enable stereo channel mirroring.
bool audio_mirroring_;
+ // Typing detector. |typing_detected_| is used to show the result of typing
+ // detection. It can be accessed by the capture audio thread and by the
+ // libjingle thread which calls GetStats().
std::unique_ptr<webrtc::TypingDetection> typing_detector_;
- // This flag is used to show the result of typing detection.
- // It can be accessed by the capture audio thread and by the libjingle thread
- // which calls GetStats().
base::subtle::Atomic32 typing_detected_;
// Communication with browser for AEC dump.
@@ -204,8 +212,8 @@ class CONTENT_EXPORT MediaStreamAudioProcessor :
// Flag to avoid executing Stop() more than once.
bool stopped_;
- // Object for logging echo information when the AEC is enabled. Accessible by
- // the libjingle thread through GetStats().
+ // Object for logging UMA stats for echo information when the AEC is enabled.
+ // Accessed on the main render thread.
std::unique_ptr<EchoInformation> echo_information_;
DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioProcessor);
diff --git a/chromium/content/renderer/media/media_stream_audio_processor_options.cc b/chromium/content/renderer/media/media_stream_audio_processor_options.cc
index 99bf7b590fb..d4ca596eac3 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor_options.cc
+++ b/chromium/content/renderer/media/media_stream_audio_processor_options.cc
@@ -48,6 +48,9 @@ const char MediaAudioConstraints::kGoogAudioMirroring[] = "googAudioMirroring";
namespace {
+// Controls whether the hotword audio stream is used on supported platforms.
+const char kMediaStreamAudioHotword[] = "googHotword";
+
// Constant constraint keys which enables default audio constraints on
// mediastreams with audio.
struct {
@@ -297,13 +300,32 @@ std::string MediaAudioConstraints::GetGoogArrayGeometry() const {
}
EchoInformation::EchoInformation()
- : num_chunks_(0), echo_frames_received_(false) {
+ : delay_stats_time_ms_(0),
+ echo_frames_received_(false),
+ divergent_filter_stats_time_ms_(0),
+ num_divergent_filter_fraction_(0),
+ num_non_zero_divergent_filter_fraction_(0) {}
+
+EchoInformation::~EchoInformation() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ReportAndResetAecDivergentFilterStats();
}
-EchoInformation::~EchoInformation() {}
+void EchoInformation::UpdateAecStats(
+ webrtc::EchoCancellation* echo_cancellation) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!echo_cancellation->is_enabled())
+ return;
+
+ UpdateAecDelayStats(echo_cancellation);
+ UpdateAecDivergentFilterStats(echo_cancellation);
+}
void EchoInformation::UpdateAecDelayStats(
webrtc::EchoCancellation* echo_cancellation) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
// Only start collecting stats if we know echo cancellation has measured an
// echo. Otherwise we clutter the stats with for example cases where only the
// microphone is used.
@@ -311,19 +333,18 @@ void EchoInformation::UpdateAecDelayStats(
return;
echo_frames_received_ = true;
+
// In WebRTC, three echo delay metrics are calculated and updated every
// five seconds. We use one of them, |fraction_poor_delays| to log in a UMA
// histogram an Echo Cancellation quality metric. The stat in WebRTC has a
// fixed aggregation window of five seconds, so we use the same query
// frequency to avoid logging old values.
- const int kNumChunksInFiveSeconds = 500;
- if (!echo_cancellation->is_delay_logging_enabled() ||
- !echo_cancellation->is_enabled()) {
+ if (!echo_cancellation->is_delay_logging_enabled())
return;
- }
- num_chunks_++;
- if (num_chunks_ < kNumChunksInFiveSeconds) {
+ delay_stats_time_ms_ += webrtc::AudioProcessing::kChunkSizeMs;
+ if (delay_stats_time_ms_ <
+ 500 * webrtc::AudioProcessing::kChunkSizeMs) { // 5 seconds
return;
}
@@ -332,7 +353,7 @@ void EchoInformation::UpdateAecDelayStats(
if (echo_cancellation->GetDelayMetrics(
&dummy_median, &dummy_std, &fraction_poor_delays) ==
webrtc::AudioProcessing::kNoError) {
- num_chunks_ = 0;
+ delay_stats_time_ms_ = 0;
// Map |fraction_poor_delays| to an Echo Cancellation quality and log in UMA
// histogram. See DelayBasedEchoQuality for information on histogram
// buckets.
@@ -342,6 +363,53 @@ void EchoInformation::UpdateAecDelayStats(
}
}
+void EchoInformation::UpdateAecDivergentFilterStats(
+ webrtc::EchoCancellation* echo_cancellation) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!echo_cancellation->are_metrics_enabled())
+ return;
+
+ divergent_filter_stats_time_ms_ += webrtc::AudioProcessing::kChunkSizeMs;
+ if (divergent_filter_stats_time_ms_ <
+ 100 * webrtc::AudioProcessing::kChunkSizeMs) { // 1 second
+ return;
+ }
+
+ webrtc::EchoCancellation::Metrics metrics;
+ if (echo_cancellation->GetMetrics(&metrics) ==
+ webrtc::AudioProcessing::kNoError) {
+ // If not yet calculated, |metrics.divergent_filter_fraction| is -1.0. After
+ // being calculated the first time, it is updated periodically.
+ if (metrics.divergent_filter_fraction < 0.0f) {
+ DCHECK_EQ(num_divergent_filter_fraction_, 0);
+ return;
+ }
+ if (metrics.divergent_filter_fraction > 0.0f) {
+ ++num_non_zero_divergent_filter_fraction_;
+ }
+ } else {
+ DLOG(WARNING) << "Get echo cancellation metrics failed.";
+ }
+ ++num_divergent_filter_fraction_;
+ divergent_filter_stats_time_ms_ = 0;
+}
+
+void EchoInformation::ReportAndResetAecDivergentFilterStats() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (num_divergent_filter_fraction_ == 0)
+ return;
+
+ int non_zero_percent = 100 * num_non_zero_divergent_filter_fraction_ /
+ num_divergent_filter_fraction_;
+ UMA_HISTOGRAM_PERCENTAGE("WebRTC.AecFilterHasDivergence", non_zero_percent);
+
+ divergent_filter_stats_time_ms_ = 0;
+ num_non_zero_divergent_filter_fraction_ = 0;
+ num_divergent_filter_fraction_ = 0;
+}
+
void EnableEchoCancellation(AudioProcessing* audio_processing) {
#if defined(OS_ANDROID)
// Mobile devices are using AECM.
diff --git a/chromium/content/renderer/media/media_stream_audio_processor_options.h b/chromium/content/renderer/media/media_stream_audio_processor_options.h
index 2d5af1d4f41..a0c6a56f4d4 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor_options.h
+++ b/chromium/content/renderer/media/media_stream_audio_processor_options.h
@@ -9,6 +9,7 @@
#include "base/files/file.h"
#include "base/macros.h"
+#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "content/public/common/media_stream_request.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
@@ -103,14 +104,36 @@ class CONTENT_EXPORT EchoInformation {
EchoInformation();
virtual ~EchoInformation();
- void UpdateAecDelayStats(webrtc::EchoCancellation* echo_cancellation);
+ // Updates stats, and reports delay metrics as UMA stats every 5 seconds.
+ // Must be called every time AudioProcessing::ProcessStream() is called.
+ void UpdateAecStats(webrtc::EchoCancellation* echo_cancellation);
+
+ // Reports AEC divergent filter metrics as UMA and resets the associated data.
+ void ReportAndResetAecDivergentFilterStats();
private:
- // Counter to track 5 seconds of processed 10 ms chunks in order to query a
- // new metric from webrtc::EchoCancellation::GetEchoDelayMetrics().
- int num_chunks_;
+ void UpdateAecDelayStats(webrtc::EchoCancellation* echo_cancellation);
+ void UpdateAecDivergentFilterStats(
+ webrtc::EchoCancellation* echo_cancellation);
+
+ // Counter to track 5 seconds of data in order to query a new metric from
+ // webrtc::EchoCancellation::GetEchoDelayMetrics().
+ int delay_stats_time_ms_;
bool echo_frames_received_;
+ // Counter to track 1 second of data in order to query a new divergent filter
+ // fraction metric from webrtc::EchoCancellation::GetMetrics().
+ int divergent_filter_stats_time_ms_;
+
+ // Total number of times we queried for the divergent filter fraction metric.
+ int num_divergent_filter_fraction_;
+
+ // Number of non-zero divergent filter fraction metrics.
+ int num_non_zero_divergent_filter_fraction_;
+
+ // Ensures that this class is accessed on the same thread.
+ base::ThreadChecker thread_checker_;
+
DISALLOW_COPY_AND_ASSIGN(EchoInformation);
};
diff --git a/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc b/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
index 8cf5cccdccf..0b5e138e7cb 100644
--- a/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_audio_processor_unittest.cc
@@ -208,6 +208,7 @@ class MediaStreamAudioProcessorTest : public ::testing::Test {
#define MAYBE_WithAudioProcessing WithAudioProcessing
#endif
TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
+ base::MessageLoop message_loop;
MockConstraintFactory constraint_factory;
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new WebRtcAudioDeviceImpl());
@@ -223,9 +224,10 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
kAudioProcessingSampleRate,
kAudioProcessingNumberOfChannel,
kAudioProcessingSampleRate / 100);
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
- // |audio_processor|.
- audio_processor = NULL;
+
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
TEST_F(MediaStreamAudioProcessorTest, VerifyTabCaptureWithoutAudioProcessing) {
@@ -259,9 +261,9 @@ TEST_F(MediaStreamAudioProcessorTest, VerifyTabCaptureWithoutAudioProcessing) {
input_device_params_, webrtc_audio_device.get());
EXPECT_FALSE(audio_processor->has_audio_processing());
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
- // |audio_processor|.
- audio_processor = NULL;
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
@@ -281,9 +283,10 @@ TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
params_.sample_rate(),
params_.channels(),
params_.sample_rate() / 100);
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
- // |audio_processor|.
- audio_processor = NULL;
+
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
TEST_F(MediaStreamAudioProcessorTest, VerifyConstraints) {
@@ -440,6 +443,7 @@ TEST_F(MediaStreamAudioProcessorTest, SelectsConstraintsArrayGeometryIfExists) {
#define MAYBE_TestAllSampleRates TestAllSampleRates
#endif
TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
+ base::MessageLoop message_loop;
MockConstraintFactory constraint_factory;
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new WebRtcAudioDeviceImpl());
@@ -467,9 +471,9 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
kAudioProcessingSampleRate / 100);
}
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device|
- // outlives |audio_processor|.
- audio_processor = NULL;
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
// Test that if we have an AEC dump message filter created, we are getting it
@@ -491,7 +495,9 @@ TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get());
- audio_processor = NULL;
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
@@ -549,9 +555,9 @@ TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
EXPECT_EQ(pushed_capture_delay, capture_delay);
}
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
- // |audio_processor|.
- audio_processor = NULL;
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
// Disabled on android clang builds due to crbug.com/470499
@@ -560,8 +566,8 @@ TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
#else
#define MAYBE_TestWithKeyboardMicChannel TestWithKeyboardMicChannel
#endif
-
TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
+ base::MessageLoop message_loop;
MockConstraintFactory constraint_factory;
constraint_factory.basic().googExperimentalNoiseSuppression.setExact(true);
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
@@ -581,9 +587,10 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
kAudioProcessingSampleRate,
kAudioProcessingNumberOfChannel,
kAudioProcessingSampleRate / 100);
- // Set |audio_processor| to NULL to make sure |webrtc_audio_device| outlives
- // |audio_processor|.
- audio_processor = NULL;
+
+ // Stop |audio_processor| so that it removes itself from
+ // |webrtc_audio_device| and clears its pointer to it.
+ audio_processor->Stop();
}
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_audio_source.cc b/chromium/content/renderer/media/media_stream_audio_source.cc
index 6e99deb54cd..8db50426ebc 100644
--- a/chromium/content/renderer/media/media_stream_audio_source.cc
+++ b/chromium/content/renderer/media/media_stream_audio_source.cc
@@ -58,7 +58,7 @@ bool MediaStreamAudioSource::ConnectToTrack(
// Create and initialize a new MediaStreamAudioTrack and pass ownership of it
// to the WebMediaStreamTrack.
blink::WebMediaStreamTrack mutable_blink_track = blink_track;
- mutable_blink_track.setExtraData(
+ mutable_blink_track.setTrackData(
CreateMediaStreamAudioTrack(blink_track.id().utf8()).release());
// Propagate initial "enabled" state.
diff --git a/chromium/content/renderer/media/media_stream_audio_track.cc b/chromium/content/renderer/media/media_stream_audio_track.cc
index 575c277e8e3..b6ec78e871f 100644
--- a/chromium/content/renderer/media/media_stream_audio_track.cc
+++ b/chromium/content/renderer/media/media_stream_audio_track.cc
@@ -31,7 +31,7 @@ MediaStreamAudioTrack* MediaStreamAudioTrack::From(
track.source().getType() != blink::WebMediaStreamSource::TypeAudio) {
return nullptr;
}
- return static_cast<MediaStreamAudioTrack*>(track.getExtraData());
+ return static_cast<MediaStreamAudioTrack*>(track.getTrackData());
}
void MediaStreamAudioTrack::AddSink(MediaStreamAudioSink* sink) {
@@ -131,4 +131,10 @@ void MediaStreamAudioTrack::OnData(const media::AudioBus& audio_bus,
}
}
+void MediaStreamAudioTrack::getSettings(
+ blink::WebMediaStreamTrack::Settings& settings) {
+ // TODO(hta): Extract the real value.
+ settings.deviceId = blink::WebString("audio device ID");
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_audio_track.h b/chromium/content/renderer/media/media_stream_audio_track.h
index c8c2b8482a8..2e43b42e756 100644
--- a/chromium/content/renderer/media/media_stream_audio_track.h
+++ b/chromium/content/renderer/media/media_stream_audio_track.h
@@ -90,6 +90,8 @@ class CONTENT_EXPORT MediaStreamAudioTrack : public MediaStreamTrack {
// delivered to the sinks instead of the content of |audio_bus|.
void OnData(const media::AudioBus& audio_bus, base::TimeTicks reference_time);
+ void getSettings(blink::WebMediaStreamTrack::Settings& settings) override;
+
private:
// In debug builds, check that all methods that could cause object graph
// or data flow changes are being called on the main thread.
diff --git a/chromium/content/renderer/media/media_stream_audio_unittest.cc b/chromium/content/renderer/media/media_stream_audio_unittest.cc
index 060dca37b07..022bedd37e3 100644
--- a/chromium/content/renderer/media/media_stream_audio_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_audio_unittest.cc
@@ -38,8 +38,11 @@ class FakeMediaStreamAudioSource
public base::PlatformThread::Delegate {
public:
FakeMediaStreamAudioSource()
- : MediaStreamAudioSource(true), stop_event_(true, false),
- next_buffer_size_(kBufferSize), sample_count_(0) {}
+ : MediaStreamAudioSource(true),
+ stop_event_(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED),
+ next_buffer_size_(kBufferSize),
+ sample_count_(0) {}
~FakeMediaStreamAudioSource() final {
CHECK(main_thread_checker_.CalledOnValidThread());
diff --git a/chromium/content/renderer/media/media_stream_center.cc b/chromium/content/renderer/media/media_stream_center.cc
index c08fcb56f27..2f5e1a40635 100644
--- a/chromium/content/renderer/media/media_stream_center.cc
+++ b/chromium/content/renderer/media/media_stream_center.cc
@@ -65,7 +65,7 @@ void CreateNativeAudioMediaStreamTrack(
void CreateNativeVideoMediaStreamTrack(
const blink::WebMediaStreamTrack& track) {
- DCHECK(track.getExtraData() == NULL);
+ DCHECK(track.getTrackData() == NULL);
blink::WebMediaStreamSource source = track.source();
DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeVideo);
MediaStreamVideoSource* native_source =
@@ -80,10 +80,9 @@ void CreateNativeVideoMediaStreamTrack(
blink::WebMediaConstraints constraints = source.constraints();
if (constraints.isNull())
constraints.initialize();
- writable_track.setExtraData(
- new MediaStreamVideoTrack(native_source, constraints,
- MediaStreamVideoSource::ConstraintsCallback(),
- track.isEnabled()));
+ writable_track.setTrackData(new MediaStreamVideoTrack(
+ native_source, constraints, MediaStreamVideoSource::ConstraintsCallback(),
+ track.isEnabled()));
}
} // namespace
@@ -97,7 +96,7 @@ MediaStreamCenter::~MediaStreamCenter() {}
void MediaStreamCenter::didCreateMediaStreamTrack(
const blink::WebMediaStreamTrack& track) {
DVLOG(1) << "MediaStreamCenter::didCreateMediaStreamTrack";
- DCHECK(!track.isNull() && !track.getExtraData());
+ DCHECK(!track.isNull() && !track.getTrackData());
DCHECK(!track.source().isNull());
switch (track.source().getType()) {
@@ -139,7 +138,7 @@ MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack(
const blink::WebMediaStreamTrack& track) {
DVLOG(1) << "MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack";
MediaStreamTrack* media_stream_track =
- static_cast<MediaStreamTrack*>(track.getExtraData());
+ static_cast<MediaStreamTrack*>(track.getTrackData());
if (!media_stream_track) {
DLOG(ERROR) << "Native track missing for webaudio source.";
return nullptr;
diff --git a/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc b/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
index 78cd37500f0..b3d137883b8 100644
--- a/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
+++ b/chromium/content/renderer/media/media_stream_renderer_factory_impl.cc
@@ -57,17 +57,17 @@ MediaStreamRendererFactoryImpl::MediaStreamRendererFactoryImpl() {
MediaStreamRendererFactoryImpl::~MediaStreamRendererFactoryImpl() {
}
-scoped_refptr<VideoFrameProvider>
-MediaStreamRendererFactoryImpl::GetVideoFrameProvider(
+scoped_refptr<MediaStreamVideoRenderer>
+MediaStreamRendererFactoryImpl::GetVideoRenderer(
const blink::WebMediaStream& web_stream,
const base::Closure& error_cb,
- const VideoFrameProvider::RepaintCB& repaint_cb,
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories) {
DCHECK(!web_stream.isNull());
- DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoFrameProvider stream:"
+ DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoRenderer stream:"
<< base::UTF16ToUTF8(base::StringPiece16(web_stream.id()));
blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
diff --git a/chromium/content/renderer/media/media_stream_renderer_factory_impl.h b/chromium/content/renderer/media/media_stream_renderer_factory_impl.h
index 33519efe73d..1305e086932 100644
--- a/chromium/content/renderer/media/media_stream_renderer_factory_impl.h
+++ b/chromium/content/renderer/media/media_stream_renderer_factory_impl.h
@@ -15,10 +15,10 @@ class MediaStreamRendererFactoryImpl : public MediaStreamRendererFactory {
MediaStreamRendererFactoryImpl();
~MediaStreamRendererFactoryImpl() override;
- scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
+ scoped_refptr<MediaStreamVideoRenderer> GetVideoRenderer(
const blink::WebMediaStream& web_stream,
const base::Closure& error_cb,
- const VideoFrameProvider::RepaintCB& repaint_cb,
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories) override;
diff --git a/chromium/content/renderer/media/media_stream_source.cc b/chromium/content/renderer/media/media_stream_source.cc
index d2b4cbf7f9b..23a459dcbfa 100644
--- a/chromium/content/renderer/media/media_stream_source.cc
+++ b/chromium/content/renderer/media/media_stream_source.cc
@@ -15,13 +15,15 @@ MediaStreamSource::MediaStreamSource() {
MediaStreamSource::~MediaStreamSource() {
DCHECK(thread_checker_.CalledOnValidThread());
- RunStopCallbackAndEndStream();
+ DCHECK(stop_callback_.is_null());
}
void MediaStreamSource::StopSource() {
DCHECK(thread_checker_.CalledOnValidThread());
DoStopSource();
- RunStopCallbackAndEndStream();
+ if (!stop_callback_.is_null())
+ base::ResetAndReturn(&stop_callback_).Run(owner());
+ owner().setReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
}
void MediaStreamSource::SetDeviceInfo(const StreamDeviceInfo& device_info) {
@@ -42,12 +44,4 @@ void MediaStreamSource::ResetSourceStoppedCallback() {
stop_callback_.Reset();
}
-void MediaStreamSource::RunStopCallbackAndEndStream() {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!stop_callback_.is_null())
- base::ResetAndReturn(&stop_callback_).Run(owner());
- if (!owner().isNull())
- owner().setReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/media_stream_source.h b/chromium/content/renderer/media/media_stream_source.h
index 7c451564d6f..23b896ae88e 100644
--- a/chromium/content/renderer/media/media_stream_source.h
+++ b/chromium/content/renderer/media/media_stream_source.h
@@ -66,11 +66,6 @@ class CONTENT_EXPORT MediaStreamSource
virtual void DoStopSource() = 0;
private:
- // Called by both StopSource() and the destructor to ensure the
- // |stop_callback_| has been run and the blink::WebMediaStreamSource's ready
- // state has been set to "ended."
- void RunStopCallbackAndEndStream();
-
StreamDeviceInfo device_info_;
SourceStoppedCallback stop_callback_;
diff --git a/chromium/content/renderer/media/media_stream_track.cc b/chromium/content/renderer/media/media_stream_track.cc
index fa0cb90d266..27fff26a874 100644
--- a/chromium/content/renderer/media/media_stream_track.cc
+++ b/chromium/content/renderer/media/media_stream_track.cc
@@ -10,7 +10,7 @@ namespace content {
MediaStreamTrack* MediaStreamTrack::GetTrack(
const blink::WebMediaStreamTrack& track) {
return track.isNull() ? nullptr
- : static_cast<MediaStreamTrack*>(track.getExtraData());
+ : static_cast<MediaStreamTrack*>(track.getTrackData());
}
MediaStreamTrack::MediaStreamTrack(bool is_local_track)
diff --git a/chromium/content/renderer/media/media_stream_track.h b/chromium/content/renderer/media/media_stream_track.h
index 8640f6a8238..c09c5088e1e 100644
--- a/chromium/content/renderer/media/media_stream_track.h
+++ b/chromium/content/renderer/media/media_stream_track.h
@@ -18,7 +18,7 @@ namespace content {
// It is owned by blink::WebMediaStreamTrack as
// blink::WebMediaStreamTrack::ExtraData.
class CONTENT_EXPORT MediaStreamTrack
- : NON_EXPORTED_BASE(public blink::WebMediaStreamTrack::ExtraData) {
+ : NON_EXPORTED_BASE(public blink::WebMediaStreamTrack::TrackData) {
public:
explicit MediaStreamTrack(bool is_local_track);
~MediaStreamTrack() override;
@@ -29,6 +29,9 @@ class CONTENT_EXPORT MediaStreamTrack
virtual void Stop() = 0;
+ // TODO(hta): Make method pure virtual when all tracks have the method.
+ void getSettings(blink::WebMediaStreamTrack::Settings& settings) override {}
+
bool is_local_track() const { return is_local_track_; }
protected:
diff --git a/chromium/content/renderer/media/media_stream_video_capturer_source.h b/chromium/content/renderer/media/media_stream_video_capturer_source.h
index a6013d0fcbb..62301bc27e3 100644
--- a/chromium/content/renderer/media/media_stream_video_capturer_source.h
+++ b/chromium/content/renderer/media/media_stream_video_capturer_source.h
@@ -56,8 +56,7 @@ class CONTENT_EXPORT MediaStreamVideoCapturerSource
const VideoCaptureDeliverFrameCB& frame_callback) override;
void StopSourceImpl() override;
- // RenderFrame does NOT own this object. Avoid unintended multiple destruction
- // by overriding RenderFrameObserver::OnDestruct().
+ // RenderFrameObserver implementation.
void OnDestruct() final {}
// Method to bind as RunningCallback in VideoCapturerSource::StartCapture().
diff --git a/chromium/content/renderer/media/media_stream_video_renderer_sink.cc b/chromium/content/renderer/media/media_stream_video_renderer_sink.cc
index f9ce2df942e..1fe5e6501a2 100644
--- a/chromium/content/renderer/media/media_stream_video_renderer_sink.cc
+++ b/chromium/content/renderer/media/media_stream_video_renderer_sink.cc
@@ -75,7 +75,7 @@ void MediaStreamVideoRendererSink::Stop() {
frame_size_.set_height(kMinFrameSize);
}
-void MediaStreamVideoRendererSink::Play() {
+void MediaStreamVideoRendererSink::Resume() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (state_ == PAUSED)
state_ = STARTED;
diff --git a/chromium/content/renderer/media/media_stream_video_renderer_sink.h b/chromium/content/renderer/media/media_stream_video_renderer_sink.h
index d858062a453..425ca6cc2c2 100644
--- a/chromium/content/renderer/media/media_stream_video_renderer_sink.h
+++ b/chromium/content/renderer/media/media_stream_video_renderer_sink.h
@@ -10,8 +10,8 @@
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/media/video_capture.h"
+#include "content/public/renderer/media_stream_video_renderer.h"
#include "content/public/renderer/media_stream_video_sink.h"
-#include "content/public/renderer/video_frame_provider.h"
#include "media/video/gpu_memory_buffer_video_frame_pool.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "ui/gfx/geometry/size.h"
@@ -27,12 +27,12 @@ class GpuVideoAcceleratorFactories;
namespace content {
-// MediaStreamVideoRendererSink is a VideoFrameProvider designed for rendering
-// Video MediaStreamTracks [1], MediaStreamVideoRendererSink implements
-// MediaStreamVideoSink in order to render video frames provided from a
-// MediaStreamVideoTrack, to which it connects itself when the
-// VideoFrameProvider is Start()ed, and disconnects itself when the latter is
-// Stop()ed.
+// MediaStreamVideoRendererSink is a MediaStreamVideoRenderer designed for
+// rendering Video MediaStreamTracks [1], MediaStreamVideoRendererSink
+// implements MediaStreamVideoSink in order to render video frames provided from
+// a MediaStreamVideoTrack, to which it connects itself when the
+// MediaStreamVideoRenderer is Start()ed, and disconnects itself when the latter
+// is Stop()ed.
//
// [1] http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
//
@@ -40,22 +40,23 @@ namespace content {
// http://src.chromium.org/viewvc/chrome/trunk/src/content/renderer/media/rtc_vi
// deo_decoder_unittest.cc?revision=180591&view=markup
class CONTENT_EXPORT MediaStreamVideoRendererSink
- : NON_EXPORTED_BASE(public VideoFrameProvider),
+ : NON_EXPORTED_BASE(public MediaStreamVideoRenderer),
NON_EXPORTED_BASE(public MediaStreamVideoSink) {
public:
MediaStreamVideoRendererSink(
const blink::WebMediaStreamTrack& video_track,
const base::Closure& error_cb,
- const RepaintCB& repaint_cb,
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories);
- // VideoFrameProvider implementation. Called on the main thread.
+ // MediaStreamVideoRenderer implementation. Called on the main thread.
void Start() override;
void Stop() override;
- void Play() override;
+ void Resume() override;
void Pause() override;
+
void SetGpuMemoryBufferVideoForTesting(
media::GpuMemoryBufferVideoFramePool* gpu_memory_buffer_pool);
diff --git a/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc b/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
index 77edaf85ce1..258b7a7bb39 100644
--- a/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_renderer_sink_unittest.cc
@@ -108,7 +108,7 @@ TEST_F(MediaStreamVideoRendererSinkTest, StartStop) {
media_stream_video_renderer_sink_->Pause();
EXPECT_TRUE(IsInPausedState());
- media_stream_video_renderer_sink_->Play(); // Should be called Resume().
+ media_stream_video_renderer_sink_->Resume();
EXPECT_TRUE(IsInStartedState());
media_stream_video_renderer_sink_->Stop();
diff --git a/chromium/content/renderer/media/media_stream_video_source.cc b/chromium/content/renderer/media/media_stream_video_source.cc
index 09ebd0ad76b..ae3df0fa96f 100644
--- a/chromium/content/renderer/media/media_stream_video_source.cc
+++ b/chromium/content/renderer/media/media_stream_video_source.cc
@@ -18,28 +18,6 @@
namespace content {
-// Constraint keys. Specified by draft-alvestrand-constraints-resolution-00b
-const char MediaStreamVideoSource::kMinAspectRatio[] = "minAspectRatio";
-const char MediaStreamVideoSource::kMaxAspectRatio[] = "maxAspectRatio";
-const char MediaStreamVideoSource::kMaxWidth[] = "maxWidth";
-const char MediaStreamVideoSource::kMinWidth[] = "minWidth";
-const char MediaStreamVideoSource::kMaxHeight[] = "maxHeight";
-const char MediaStreamVideoSource::kMinHeight[] = "minHeight";
-const char MediaStreamVideoSource::kMaxFrameRate[] = "maxFrameRate";
-const char MediaStreamVideoSource::kMinFrameRate[] = "minFrameRate";
-
-// TODO(mcasas): Find a way to guarantee all constraints are added to the array.
-const char* const kSupportedConstraints[] = {
- MediaStreamVideoSource::kMaxAspectRatio,
- MediaStreamVideoSource::kMinAspectRatio,
- MediaStreamVideoSource::kMaxWidth,
- MediaStreamVideoSource::kMinWidth,
- MediaStreamVideoSource::kMaxHeight,
- MediaStreamVideoSource::kMinHeight,
- MediaStreamVideoSource::kMaxFrameRate,
- MediaStreamVideoSource::kMinFrameRate,
-};
-
namespace {
const char* const kLegalVideoConstraints[] = {
@@ -305,14 +283,6 @@ MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
return static_cast<MediaStreamVideoSource*>(source.getExtraData());
}
-// static, deprecated
-bool MediaStreamVideoSource::IsConstraintSupported(const std::string& name) {
- return std::find(kSupportedConstraints,
- kSupportedConstraints + arraysize(kSupportedConstraints),
- name) !=
- kSupportedConstraints + arraysize(kSupportedConstraints);
-}
-
MediaStreamVideoSource::MediaStreamVideoSource()
: state_(NEW),
track_adapter_(
diff --git a/chromium/content/renderer/media/media_stream_video_source.h b/chromium/content/renderer/media/media_stream_video_source.h
index 550adea207b..3d79aeafb77 100644
--- a/chromium/content/renderer/media/media_stream_video_source.h
+++ b/chromium/content/renderer/media/media_stream_video_source.h
@@ -47,17 +47,6 @@ class CONTENT_EXPORT MediaStreamVideoSource
: public MediaStreamSource,
NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
- // Constraint keys used by a video source.
- // Specified by draft-alvestrand-constraints-resolution-00b
- static const char kMinAspectRatio[]; // minAspectRatio
- static const char kMaxAspectRatio[]; // maxAspectRatio
- static const char kMaxWidth[]; // maxWidth
- static const char kMinWidth[]; // minWidth
- static const char kMaxHeight[]; // maxHeight
- static const char kMinHeight[]; // minHeight
- static const char kMaxFrameRate[]; // maxFrameRate
- static const char kMinFrameRate[]; // minFrameRate
-
enum {
// Default resolution. If no constraints are specified and the delegate
// support it, this is the resolution that will be used.
@@ -84,9 +73,6 @@ class CONTENT_EXPORT MediaStreamVideoSource
void UpdateCapturingLinkSecure(MediaStreamVideoTrack* track, bool is_secure);
- // Return true if |name| is a constraint supported by MediaStreamVideoSource.
- static bool IsConstraintSupported(const std::string& name);
-
// Request underlying source to capture a new frame.
virtual void RequestRefreshFrame() {}
diff --git a/chromium/content/renderer/media/media_stream_video_source_unittest.cc b/chromium/content/renderer/media/media_stream_video_source_unittest.cc
index 8509243a8ac..64395970c04 100644
--- a/chromium/content/renderer/media/media_stream_video_source_unittest.cc
+++ b/chromium/content/renderer/media/media_stream_video_source_unittest.cc
@@ -681,28 +681,6 @@ TEST_F(MediaStreamVideoSourceTest, SourceChangeFrameSize) {
sink.DisconnectFromTrack();
}
-TEST_F(MediaStreamVideoSourceTest, IsConstraintSupported) {
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMaxFrameRate));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMinFrameRate));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMaxWidth));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMinWidth));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMaxHeight));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMinHeight));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMaxAspectRatio));
- EXPECT_TRUE(MediaStreamVideoSource::IsConstraintSupported(
- MediaStreamVideoSource::kMinAspectRatio));
-
- EXPECT_FALSE(MediaStreamVideoSource::IsConstraintSupported(
- "something unsupported"));
-}
-
// Test that the constraint negotiation can handle 0.0 fps as frame rate.
TEST_F(MediaStreamVideoSourceTest, Use0FpsSupportedFormat) {
media::VideoCaptureFormats formats;
diff --git a/chromium/content/renderer/media/media_stream_video_track.cc b/chromium/content/renderer/media/media_stream_video_track.cc
index 74893dcc424..e23b290328d 100644
--- a/chromium/content/renderer/media/media_stream_video_track.cc
+++ b/chromium/content/renderer/media/media_stream_video_track.cc
@@ -202,10 +202,8 @@ blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
bool enabled) {
blink::WebMediaStreamTrack track;
track.initialize(source->owner());
- track.setExtraData(new MediaStreamVideoTrack(source,
- constraints,
- callback,
- enabled));
+ track.setTrackData(
+ new MediaStreamVideoTrack(source, constraints, callback, enabled));
return track;
}
@@ -216,7 +214,7 @@ MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
track.source().getType() != blink::WebMediaStreamSource::TypeVideo) {
return nullptr;
}
- return static_cast<MediaStreamVideoTrack*>(track.getExtraData());
+ return static_cast<MediaStreamVideoTrack*>(track.getTrackData());
}
MediaStreamVideoTrack::MediaStreamVideoTrack(
@@ -290,6 +288,20 @@ void MediaStreamVideoTrack::Stop() {
OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
}
+void MediaStreamVideoTrack::getSettings(
+ blink::WebMediaStreamTrack::Settings& settings) {
+ if (source_) {
+ const media::VideoCaptureFormat* format = source_->GetCurrentFormat();
+ if (format) {
+ settings.frameRate = format->frame_rate;
+ settings.width = format->frame_size.width();
+ settings.height = format->frame_size.height();
+ }
+ }
+ // TODO(hta): Extract the real value.
+ settings.deviceId = blink::WebString("video device ID");
+}
+
void MediaStreamVideoTrack::OnReadyStateChanged(
blink::WebMediaStreamSource::ReadyState state) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
diff --git a/chromium/content/renderer/media/media_stream_video_track.h b/chromium/content/renderer/media/media_stream_video_track.h
index e74e3bc2924..436c15f86ac 100644
--- a/chromium/content/renderer/media/media_stream_video_track.h
+++ b/chromium/content/renderer/media/media_stream_video_track.h
@@ -53,6 +53,7 @@ class CONTENT_EXPORT MediaStreamVideoTrack : public MediaStreamTrack {
// MediaStreamTrack overrides.
void SetEnabled(bool enabled) override;
void Stop() override;
+ void getSettings(blink::WebMediaStreamTrack::Settings& settings) override;
void OnReadyStateChanged(blink::WebMediaStreamSource::ReadyState state);
diff --git a/chromium/content/renderer/media/midi_dispatcher.cc b/chromium/content/renderer/media/midi_dispatcher.cc
index 65f42a95d44..f870105dee7 100644
--- a/chromium/content/renderer/media/midi_dispatcher.cc
+++ b/chromium/content/renderer/media/midi_dispatcher.cc
@@ -5,10 +5,11 @@
#include "content/renderer/media/midi_dispatcher.h"
#include "base/bind.h"
-#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_frame.h"
+#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/modules/webmidi/WebMIDIOptions.h"
#include "third_party/WebKit/public/web/modules/webmidi/WebMIDIPermissionRequest.h"
@@ -24,12 +25,14 @@ MidiDispatcher::MidiDispatcher(RenderFrame* render_frame)
MidiDispatcher::~MidiDispatcher() {}
+void MidiDispatcher::OnDestruct() {
+ delete this;
+}
+
void MidiDispatcher::requestPermission(const WebMIDIPermissionRequest& request,
const WebMIDIOptions& options) {
- if (!permission_service_.get()) {
- render_frame()->GetServiceRegistry()->ConnectToRemoteService(
- mojo::GetProxy(&permission_service_));
- }
+ if (!permission_service_.get())
+ render_frame()->GetRemoteInterfaces()->GetInterface(&permission_service_);
int permission_request_id =
requests_.Add(new WebMIDIPermissionRequest(request));
@@ -41,6 +44,7 @@ void MidiDispatcher::requestPermission(const WebMIDIPermissionRequest& request,
permission_service_->RequestPermission(
permission_name, request.getSecurityOrigin().toString().utf8(),
+ blink::WebUserGestureIndicator::isProcessingUserGesture(),
base::Bind(&MidiDispatcher::OnPermissionSet, base::Unretained(this),
permission_request_id));
}
diff --git a/chromium/content/renderer/media/midi_dispatcher.h b/chromium/content/renderer/media/midi_dispatcher.h
index 802328a770c..2d98117d092 100644
--- a/chromium/content/renderer/media/midi_dispatcher.h
+++ b/chromium/content/renderer/media/midi_dispatcher.h
@@ -28,6 +28,9 @@ class MidiDispatcher : public RenderFrameObserver,
~MidiDispatcher() override;
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// blink::WebMIDIClient implementation.
void requestPermission(const blink::WebMIDIPermissionRequest& request,
const blink::WebMIDIOptions& options) override;
diff --git a/chromium/content/renderer/media/mock_media_stream_registry.cc b/chromium/content/renderer/media/mock_media_stream_registry.cc
index bad1ae790c6..91fb227ecf1 100644
--- a/chromium/content/renderer/media/mock_media_stream_registry.cc
+++ b/chromium/content/renderer/media/mock_media_stream_registry.cc
@@ -72,7 +72,7 @@ void MockMediaStreamRegistry::AddVideoTrack(const std::string& track_id) {
MediaStreamVideoTrack* native_track = new MediaStreamVideoTrack(
native_source, constraints, MediaStreamVideoSource::ConstraintsCallback(),
true /* enabled */);
- blink_track.setExtraData(native_track);
+ blink_track.setTrackData(native_track);
test_stream_.addTrack(blink_track);
}
diff --git a/chromium/content/renderer/media/peer_connection_identity_store.h b/chromium/content/renderer/media/peer_connection_identity_store.h
index cdd0ec29836..3172a2cabf4 100644
--- a/chromium/content/renderer/media/peer_connection_identity_store.h
+++ b/chromium/content/renderer/media/peer_connection_identity_store.h
@@ -16,6 +16,8 @@ namespace content {
// This class is associated with a peer connection and handles WebRTC DTLS
// identity requests by delegating to the per-renderer WebRTCIdentityProxy.
+// TODO(hbos): Remove this store, it is no longer used.
+// See bugs.webrtc.org/5707, bugs.webrtc.org/5708.
class PeerConnectionIdentityStore
: public webrtc::DtlsIdentityStoreInterface {
public:
diff --git a/chromium/content/renderer/media/pepper_to_video_track_adapter.cc b/chromium/content/renderer/media/pepper_to_video_track_adapter.cc
index f1dfa51f6fe..afd3b20be0f 100644
--- a/chromium/content/renderer/media/pepper_to_video_track_adapter.cc
+++ b/chromium/content/renderer/media/pepper_to_video_track_adapter.cc
@@ -209,7 +209,7 @@ class PpFrameWriterProxy : public FrameWriterInterface {
public:
explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer)
: writer_(writer) {
- DCHECK(writer_ != NULL);
+ DCHECK(writer_);
}
~PpFrameWriterProxy() override {}
diff --git a/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc b/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
index 0c13cb6fff7..da0d50cb975 100644
--- a/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/pepper_to_video_track_adapter_unittest.cc
@@ -98,7 +98,7 @@ TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
// PostTaskAndReply to the IO thread and expects the reply to process
// on the main render thread to clean up its resources. However, the
// QuitClosure above ends before that.
- base::MessageLoop::current()->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
EXPECT_EQ(1, sink.number_of_frames());
native_track->RemoveSink(&sink);
diff --git a/chromium/content/renderer/media/remote_media_stream_impl.cc b/chromium/content/renderer/media/remote_media_stream_impl.cc
index 5f449c03821..8dca0e663cd 100644
--- a/chromium/content/renderer/media/remote_media_stream_impl.cc
+++ b/chromium/content/renderer/media/remote_media_stream_impl.cc
@@ -167,7 +167,7 @@ class RemoteVideoTrackAdapter
MediaStreamVideoTrack* media_stream_track =
new MediaStreamVideoTrack(video_source.release(), constraints,
MediaStreamVideoSource::ConstraintsCallback(), enabled);
- webkit_track()->setExtraData(media_stream_track);
+ webkit_track()->setTrackData(media_stream_track);
}
};
diff --git a/chromium/content/renderer/media/render_media_log.cc b/chromium/content/renderer/media/render_media_log.cc
index bcc3301aa35..25defe5c466 100644
--- a/chromium/content/renderer/media/render_media_log.cc
+++ b/chromium/content/renderer/media/render_media_log.cc
@@ -13,6 +13,8 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "content/common/view_messages.h"
+#include "content/public/common/content_client.h"
+#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread.h"
namespace {
@@ -34,8 +36,9 @@ void Log(media::MediaLogEvent* event) {
namespace content {
-RenderMediaLog::RenderMediaLog()
- : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+RenderMediaLog::RenderMediaLog(const GURL& security_origin)
+ : security_origin_(security_origin),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
tick_clock_(new base::DefaultTickClock()),
last_ipc_send_time_(tick_clock_->NowTicks()),
ipc_send_pending_(false) {
@@ -118,6 +121,17 @@ std::string RenderMediaLog::GetLastErrorMessage() {
return result.str();
}
+void RenderMediaLog::RecordRapporWithSecurityOrigin(const std::string& metric) {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&RenderMediaLog::RecordRapporWithSecurityOrigin,
+ this, metric));
+ return;
+ }
+
+ GetContentClient()->renderer()->RecordRapporURL(metric, security_origin_);
+}
+
void RenderMediaLog::SendQueuedMediaEvents() {
DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/chromium/content/renderer/media/render_media_log.h b/chromium/content/renderer/media/render_media_log.h
index 3606b98e928..e9b655aed4b 100644
--- a/chromium/content/renderer/media/render_media_log.h
+++ b/chromium/content/renderer/media/render_media_log.h
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "media/base/media_log.h"
+#include "url/gurl.h"
namespace base {
class TickClock;
@@ -32,11 +33,12 @@ namespace content {
// It must be constructed on the render thread.
class CONTENT_EXPORT RenderMediaLog : public media::MediaLog {
public:
- RenderMediaLog();
+ explicit RenderMediaLog(const GURL& security_origin);
// MediaLog implementation.
void AddEvent(std::unique_ptr<media::MediaLogEvent> event) override;
std::string GetLastErrorMessage() override;
+ void RecordRapporWithSecurityOrigin(const std::string& metric) override;
// Will reset |last_ipc_send_time_| with the value of NowTicks().
void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
@@ -50,6 +52,9 @@ class CONTENT_EXPORT RenderMediaLog : public media::MediaLog {
// frequency.
void SendQueuedMediaEvents();
+ // Security origin of the current frame.
+ const GURL security_origin_;
+
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// |lock_| protects access to all of the following member variables. It
diff --git a/chromium/content/renderer/media/render_media_log_unittest.cc b/chromium/content/renderer/media/render_media_log_unittest.cc
index 131da078c19..c383dcd86a1 100644
--- a/chromium/content/renderer/media/render_media_log_unittest.cc
+++ b/chromium/content/renderer/media/render_media_log_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_mock_time_task_runner.h"
@@ -15,7 +17,7 @@ namespace content {
class RenderMediaLogTest : public testing::Test {
public:
RenderMediaLogTest()
- : log_(new RenderMediaLog()),
+ : log_(new RenderMediaLog(GURL("http://foo.com"))),
tick_clock_(new base::SimpleTestTickClock()),
task_runner_(new base::TestMockTimeTaskRunner()) {
log_->SetTickClockForTesting(std::unique_ptr<base::TickClock>(tick_clock_));
@@ -47,9 +49,9 @@ class RenderMediaLogTest : public testing::Test {
return std::vector<media::MediaLogEvent>();
}
- base::Tuple<std::vector<media::MediaLogEvent>> events;
+ std::tuple<std::vector<media::MediaLogEvent>> events;
ViewHostMsg_MediaLogEvents::Read(msg, &events);
- return base::get<0>(events);
+ return std::get<0>(events);
}
private:
diff --git a/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc b/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
index a9fba3b4e21..7f648538c69 100644
--- a/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -72,7 +72,7 @@ void RendererWebAudioDeviceImpl::start() {
RenderFrame* const render_frame =
web_frame ? RenderFrame::FromWebFrame(web_frame) : NULL;
sink_ = AudioDeviceFactory::NewAudioRendererSink(
- AudioDeviceFactory::kSourceWebAudio,
+ AudioDeviceFactory::kSourceWebAudioInteractive,
render_frame ? render_frame->GetRoutingID() : MSG_ROUTING_NONE,
session_id_, std::string(), security_origin_);
sink_->Initialize(params_, this);
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
index 57a25e69958..f3b8125aa29 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -174,4 +174,8 @@ void RendererWebMediaPlayerDelegate::CleanupIdleDelegates() {
idle_cleanup_timer_.Stop();
}
+void RendererWebMediaPlayerDelegate::OnDestruct() {
+ delete this;
+}
+
} // namespace media
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
index b12a58f971d..0e8307744c1 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -53,6 +53,7 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
void WasHidden() override;
void WasShown() override;
bool OnMessageReceived(const IPC::Message& msg) override;
+ void OnDestruct() override;
// Zeros out |idle_cleanup_interval_|, and sets |idle_timeout_| to
// |idle_timeout|. A zero cleanup interval will cause the idle timer to run
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
index 4872ec891cd..4fe4fdb4525 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/location.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/test/simple_test_tick_clock.h"
-#include "base/tuple.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/common/media/media_player_delegate_messages.h"
#include "content/public/renderer/render_view.h"
#include "content/public/test/render_view_test.h"
@@ -78,13 +82,13 @@ TEST_F(RendererWebMediaPlayerDelegateTest, SendsMessagesCorrectly) {
MediaPlayerDelegateHostMsg_OnMediaPlaying::ID);
ASSERT_TRUE(msg);
- base::Tuple<int, bool, bool, bool, base::TimeDelta> result;
+ std::tuple<int, bool, bool, bool, base::TimeDelta> result;
ASSERT_TRUE(MediaPlayerDelegateHostMsg_OnMediaPlaying::Read(msg, &result));
- EXPECT_EQ(delegate_id, base::get<0>(result));
- EXPECT_EQ(kHasVideo, base::get<1>(result));
- EXPECT_EQ(kHasAudio, base::get<2>(result));
- EXPECT_EQ(kIsRemote, base::get<3>(result));
- EXPECT_EQ(kDuration, base::get<4>(result));
+ EXPECT_EQ(delegate_id, std::get<0>(result));
+ EXPECT_EQ(kHasVideo, std::get<1>(result));
+ EXPECT_EQ(kHasAudio, std::get<2>(result));
+ EXPECT_EQ(kIsRemote, std::get<3>(result));
+ EXPECT_EQ(kDuration, std::get<4>(result));
}
// Verify the paused message.
@@ -97,10 +101,10 @@ TEST_F(RendererWebMediaPlayerDelegateTest, SendsMessagesCorrectly) {
MediaPlayerDelegateHostMsg_OnMediaPaused::ID);
ASSERT_TRUE(msg);
- base::Tuple<int, bool> result;
+ std::tuple<int, bool> result;
ASSERT_TRUE(MediaPlayerDelegateHostMsg_OnMediaPaused::Read(msg, &result));
- EXPECT_EQ(delegate_id, base::get<0>(result));
- EXPECT_EQ(kReachedEndOfStream, base::get<1>(result));
+ EXPECT_EQ(delegate_id, std::get<0>(result));
+ EXPECT_EQ(kReachedEndOfStream, std::get<1>(result));
}
// Verify the destruction message.
@@ -111,10 +115,10 @@ TEST_F(RendererWebMediaPlayerDelegateTest, SendsMessagesCorrectly) {
MediaPlayerDelegateHostMsg_OnMediaDestroyed::ID);
ASSERT_TRUE(msg);
- base::Tuple<int> result;
+ std::tuple<int> result;
ASSERT_TRUE(
MediaPlayerDelegateHostMsg_OnMediaDestroyed::Read(msg, &result));
- EXPECT_EQ(delegate_id, base::get<0>(result));
+ EXPECT_EQ(delegate_id, std::get<0>(result));
}
delegate_manager_->RemoveObserver(delegate_id);
@@ -184,7 +188,8 @@ TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesAreSuspended) {
&RendererWebMediaPlayerDelegate::PlayerGone,
base::Unretained(delegate_manager_.get()), delegate_id_2)));
base::RunLoop run_loop;
- base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1));
run_loop.Run();
}
@@ -203,7 +208,8 @@ TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesAreSuspended) {
EXPECT_CALL(observer_1, OnSuspendRequested(false))
.Times(testing::AtLeast(1));
base::RunLoop run_loop;
- base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1));
run_loop.Run();
}
@@ -222,7 +228,8 @@ TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesAreSuspended) {
&RendererWebMediaPlayerDelegate::PlayerGone,
base::Unretained(delegate_manager_.get()), delegate_id_1)));
base::RunLoop run_loop;
- base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1));
run_loop.Run();
}
@@ -253,7 +260,8 @@ TEST_F(RendererWebMediaPlayerDelegateTest, IdleDelegatesIgnoresSuspendRequest) {
// Wait for the suspend request, but don't call PlayerGone().
EXPECT_CALL(observer_1, OnSuspendRequested(false));
base::RunLoop run_loop;
- base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
tick_clock.Advance(kIdleTimeout + base::TimeDelta::FromMicroseconds(1));
run_loop.Run();
diff --git a/chromium/content/renderer/media/rtc_certificate_generator.cc b/chromium/content/renderer/media/rtc_certificate_generator.cc
index 94b94fb1c89..94626e50063 100644
--- a/chromium/content/renderer/media/rtc_certificate_generator.cc
+++ b/chromium/content/renderer/media/rtc_certificate_generator.cc
@@ -9,11 +9,13 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "content/renderer/media/peer_connection_identity_store.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "content/renderer/media/rtc_certificate.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
#include "content/renderer/render_thread_impl.h"
#include "third_party/webrtc/base/rtccertificate.h"
+#include "third_party/webrtc/base/rtccertificategenerator.h"
#include "third_party/webrtc/base/scoped_ref_ptr.h"
#include "url/gurl.h"
@@ -35,158 +37,109 @@ rtc::KeyParams WebRTCKeyParamsToKeyParams(
}
}
-// Observer used by RTCCertificateGenerator::generateCertificate.
-class RTCCertificateIdentityObserver
- : public webrtc::DtlsIdentityRequestObserver {
+// A certificate generation request spawned by
+// |RTCCertificateGenerator::generateCertificateWithOptionalExpiration|. This
+// is handled by a separate class so that reference counting can keep the
+// request alive independently of the |RTCCertificateGenerator| that spawned it.
+class RTCCertificateGeneratorRequest
+ : public base::RefCountedThreadSafe<RTCCertificateGeneratorRequest> {
public:
- RTCCertificateIdentityObserver(
+ RTCCertificateGeneratorRequest(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread)
+ const scoped_refptr<base::SingleThreadTaskRunner>& worker_thread)
: main_thread_(main_thread),
- signaling_thread_(signaling_thread),
- observer_(nullptr) {
+ worker_thread_(worker_thread) {
DCHECK(main_thread_);
- DCHECK(signaling_thread_);
+ DCHECK(worker_thread_);
}
- ~RTCCertificateIdentityObserver() override {}
- // Perform |store|->RequestIdentity with this identity observer and ensure
- // that this identity observer is not deleted until the request has completed
- // by holding on to a reference to itself for the duration of the request.
- void RequestIdentity(
+ void GenerateCertificateAsync(
const blink::WebRTCKeyParams& key_params,
- const GURL& url,
- const GURL& first_party_for_cookies,
const rtc::Optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!observer_) << "Already have a RequestIdentity in progress.";
- key_params_ = key_params;
- observer_ = std::move(observer);
- DCHECK(observer_);
- // Identity request must be performed on the WebRTC signaling thread.
- signaling_thread_->PostTask(FROM_HERE, base::Bind(
- &RTCCertificateIdentityObserver::RequestIdentityOnWebRtcSignalingThread,
- this, url, first_party_for_cookies, expires_ms));
+ DCHECK(observer);
+ worker_thread_->PostTask(FROM_HERE, base::Bind(
+ &RTCCertificateGeneratorRequest::GenerateCertificateOnWorkerThread,
+ this,
+ key_params,
+ expires_ms,
+ base::Passed(std::move(observer))));
}
private:
- void RequestIdentityOnWebRtcSignalingThread(
- GURL url,
- GURL first_party_for_cookies,
- rtc::Optional<uint64_t> expires_ms) {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
- std::unique_ptr<PeerConnectionIdentityStore> store(
- new PeerConnectionIdentityStore(main_thread_, signaling_thread_, url,
- first_party_for_cookies));
- // Request identity with |this| as the observer. OnSuccess/OnFailure will be
- // called asynchronously.
- store->RequestIdentity(WebRTCKeyParamsToKeyParams(key_params_),
- expires_ms, this);
- }
+ friend class base::RefCountedThreadSafe<RTCCertificateGeneratorRequest>;
+ ~RTCCertificateGeneratorRequest() {}
+
+ void GenerateCertificateOnWorkerThread(
+ const blink::WebRTCKeyParams key_params,
+ const rtc::Optional<uint64_t> expires_ms,
+ std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
+ DCHECK(worker_thread_->BelongsToCurrentThread());
- // webrtc::DtlsIdentityRequestObserver implementation.
- void OnFailure(int error) override {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
- DCHECK(observer_);
- main_thread_->PostTask(FROM_HERE, base::Bind(
- &RTCCertificateIdentityObserver::DoCallbackOnMainThread,
- this, nullptr));
- }
- void OnSuccess(const std::string& der_cert,
- const std::string& der_private_key) override {
- std::string pem_cert = rtc::SSLIdentity::DerToPem(
- rtc::kPemTypeCertificate,
- reinterpret_cast<const unsigned char*>(der_cert.data()),
- der_cert.length());
- std::string pem_key = rtc::SSLIdentity::DerToPem(
- rtc::kPemTypeRsaPrivateKey,
- reinterpret_cast<const unsigned char*>(der_private_key.data()),
- der_private_key.length());
- OnSuccess(std::unique_ptr<rtc::SSLIdentity>(
- rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)));
- }
- void OnSuccess(std::unique_ptr<rtc::SSLIdentity> identity) override {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
- DCHECK(observer_);
rtc::scoped_refptr<rtc::RTCCertificate> certificate =
- rtc::RTCCertificate::Create(std::move(identity));
- main_thread_->PostTask(
- FROM_HERE,
- base::Bind(&RTCCertificateIdentityObserver::DoCallbackOnMainThread,
- this, base::Passed(base::WrapUnique(
- new RTCCertificate(certificate)))));
+ rtc::RTCCertificateGenerator::GenerateCertificate(
+ WebRTCKeyParamsToKeyParams(key_params), expires_ms);
+
+ main_thread_->PostTask(FROM_HERE, base::Bind(
+ &RTCCertificateGeneratorRequest::DoCallbackOnMainThread,
+ this,
+ base::Passed(std::move(observer)),
+ base::Passed(base::WrapUnique(new RTCCertificate(certificate)))));
}
void DoCallbackOnMainThread(
+ std::unique_ptr<blink::WebRTCCertificateCallback> observer,
std::unique_ptr<blink::WebRTCCertificate> certificate) {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(observer_);
+ DCHECK(observer);
if (certificate)
- observer_->onSuccess(std::move(certificate));
+ observer->onSuccess(std::move(certificate));
else
- observer_->onError();
- observer_.reset();
+ observer->onError();
}
// The main thread is the renderer thread.
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- // The signaling thread is a WebRTC thread used to invoke
- // PeerConnectionIdentityStore::RequestIdentity on, as is required.
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
- blink::WebRTCKeyParams key_params_;
- std::unique_ptr<blink::WebRTCCertificateCallback> observer_;
-
- DISALLOW_COPY_AND_ASSIGN(RTCCertificateIdentityObserver);
+ // The WebRTC worker thread.
+ const scoped_refptr<base::SingleThreadTaskRunner> worker_thread_;
};
} // namespace
void RTCCertificateGenerator::generateCertificate(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
generateCertificateWithOptionalExpiration(
- key_params, url, first_party_for_cookies, rtc::Optional<uint64_t>(),
- std::move(observer));
+ key_params, rtc::Optional<uint64_t>(), std::move(observer));
}
void RTCCertificateGenerator::generateCertificateWithExpiration(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
generateCertificateWithOptionalExpiration(
- key_params, url, first_party_for_cookies,
- rtc::Optional<uint64_t>(expires_ms), std::move(observer));
+ key_params, rtc::Optional<uint64_t>(expires_ms), std::move(observer));
}
void RTCCertificateGenerator::generateCertificateWithOptionalExpiration(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
const rtc::Optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
DCHECK(isSupportedKeyParams(key_params));
-
#if defined(ENABLE_WEBRTC)
const scoped_refptr<base::SingleThreadTaskRunner> main_thread =
base::ThreadTaskRunnerHandle::Get();
-
PeerConnectionDependencyFactory* pc_dependency_factory =
RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
pc_dependency_factory->EnsureInitialized();
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread =
- pc_dependency_factory->GetWebRtcSignalingThread();
-
- rtc::scoped_refptr<RTCCertificateIdentityObserver> identity_observer(
- new rtc::RefCountedObject<RTCCertificateIdentityObserver>(
- main_thread, signaling_thread));
- // |identity_observer| lives until request has completed.
- identity_observer->RequestIdentity(key_params, url, first_party_for_cookies,
- expires_ms, std::move(observer));
+
+ scoped_refptr<RTCCertificateGeneratorRequest> request =
+ new RTCCertificateGeneratorRequest(
+ main_thread,
+ pc_dependency_factory->GetWebRtcWorkerThread());
+ request->GenerateCertificateAsync(
+ key_params, expires_ms, std::move(observer));
#else
observer->onError();
#endif
diff --git a/chromium/content/renderer/media/rtc_certificate_generator.h b/chromium/content/renderer/media/rtc_certificate_generator.h
index 3858db265cc..38811e5ef95 100644
--- a/chromium/content/renderer/media/rtc_certificate_generator.h
+++ b/chromium/content/renderer/media/rtc_certificate_generator.h
@@ -24,13 +24,9 @@ class RTCCertificateGenerator : public blink::WebRTCCertificateGenerator {
// blink::WebRTCCertificateGenerator implementation.
void generateCertificate(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) override;
void generateCertificateWithExpiration(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) override;
bool isSupportedKeyParams(const blink::WebRTCKeyParams& key_params) override;
@@ -41,8 +37,6 @@ class RTCCertificateGenerator : public blink::WebRTCCertificateGenerator {
private:
void generateCertificateWithOptionalExpiration(
const blink::WebRTCKeyParams& key_params,
- const blink::WebURL& url,
- const blink::WebURL& first_party_for_cookies,
const rtc::Optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer);
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler.cc b/chromium/content/renderer/media/rtc_peer_connection_handler.cc
index e273e5113a9..361948cde06 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler.cc
@@ -722,21 +722,6 @@ void ConvertConstraintsToWebrtcOfferOptions(
base::LazyInstance<std::set<RTCPeerConnectionHandler*> >::Leaky
g_peer_connection_handlers = LAZY_INSTANCE_INITIALIZER;
-void OverrideDefaultCertificateBasedOnExperiment(
- webrtc::PeerConnectionInterface::RTCConfiguration* config) {
- if (base::FeatureList::IsEnabled(features::kWebRtcEcdsaDefault)) {
- if (config->certificates.empty()) {
- rtc::scoped_refptr<rtc::RTCCertificate> certificate =
- PeerConnectionDependencyFactory::GenerateDefaultCertificate();
- config->certificates.push_back(certificate);
- }
- }
- // If the ECDSA experiment is not running we rely on the default being RSA for
- // the control group. See bug related to this: crbug.com/611698.
- static_assert(rtc::KT_DEFAULT == rtc::KT_RSA, "This code relies on "
- "KT_DEFAULT == KT_RSA for RSA certificate generation.");
-}
-
} // namespace
// Implementation of LocalRTCStatsRequest.
@@ -811,7 +796,7 @@ class RTCPeerConnectionHandler::Observer
}
}
- void OnAddStream(MediaStreamInterface* stream) override {
+ void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
DCHECK(stream);
std::unique_ptr<RemoteMediaStreamImpl> remote_stream(
new RemoteMediaStreamImpl(main_thread_, stream));
@@ -824,13 +809,16 @@ class RTCPeerConnectionHandler::Observer
this, base::Passed(&remote_stream)));
}
- void OnRemoveStream(MediaStreamInterface* stream) override {
- main_thread_->PostTask(FROM_HERE,
+ void OnRemoveStream(
+ rtc::scoped_refptr<MediaStreamInterface> stream) override {
+ main_thread_->PostTask(
+ FROM_HERE,
base::Bind(&RTCPeerConnectionHandler::Observer::OnRemoveStreamImpl,
- this, make_scoped_refptr(stream)));
+ this, make_scoped_refptr(stream.get())));
}
- void OnDataChannel(DataChannelInterface* data_channel) override {
+ void OnDataChannel(
+ rtc::scoped_refptr<DataChannelInterface> data_channel) override {
std::unique_ptr<RtcDataChannelHandler> handler(
new RtcDataChannelHandler(main_thread_, data_channel));
main_thread_->PostTask(FROM_HERE,
@@ -967,7 +955,6 @@ bool RTCPeerConnectionHandler::initialize(
webrtc::PeerConnectionInterface::RTCConfiguration config;
GetNativeRtcConfiguration(server_configuration, &config);
- OverrideDefaultCertificateBasedOnExperiment(&config);
// Choose between RTC smoothness algorithm and prerenderer smoothing.
// Prerenderer smoothing is turned on if RTC smoothness is turned off.
@@ -1004,7 +991,6 @@ bool RTCPeerConnectionHandler::InitializeForTest(
DCHECK(thread_checker_.CalledOnValidThread());
webrtc::PeerConnectionInterface::RTCConfiguration config;
GetNativeRtcConfiguration(server_configuration, &config);
- OverrideDefaultCertificateBasedOnExperiment(&config);
peer_connection_observer_ = new Observer(weak_factory_.GetWeakPtr());
CopyConstraintsIntoRtcConfiguration(options, &config);
@@ -1270,6 +1256,12 @@ bool RTCPeerConnectionHandler::updateICE(
return native_peer_connection_->UpdateIce(config.servers);
}
+void RTCPeerConnectionHandler::logSelectedRtcpMuxPolicy(
+ blink::RtcpMuxPolicy selectedRtcpMuxPolicy) {
+ UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SelectedRtcpMuxPolicy",
+ selectedRtcpMuxPolicy, blink::RtcpMuxPolicyMax);
+}
+
bool RTCPeerConnectionHandler::addICECandidate(
const blink::WebRTCVoidRequest& request,
const blink::WebRTCICECandidate& candidate) {
@@ -1779,7 +1771,8 @@ void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
TRACE_EVENT0("webrtc", trace_event_name);
closure.Run();
} else {
- base::WaitableEvent event(false, false);
+ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
thread->PostTask(FROM_HERE,
base::Bind(&RunSynchronousClosure, closure,
base::Unretained(trace_event_name),
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler.h b/chromium/content/renderer/media/rtc_peer_connection_handler.h
index 7fe3bf259b7..04941df562c 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler.h
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler.h
@@ -135,6 +135,8 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
bool updateICE(
const blink::WebRTCConfiguration& server_configuration) override;
+ void logSelectedRtcpMuxPolicy(
+ blink::RtcpMuxPolicy selectedRtcpMuxPolicy) override;
bool addICECandidate(const blink::WebRTCICECandidate& candidate) override;
bool addICECandidate(const blink::WebRTCVoidRequest& request,
const blink::WebRTCICECandidate& candidate) override;
diff --git a/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index cd65ee7bca9..1032489c621 100644
--- a/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/chromium/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -305,19 +305,19 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
// Creates a remote MediaStream and adds it to the mocked native
// peer connection.
- scoped_refptr<webrtc::MediaStreamInterface>
- AddRemoteMockMediaStream(const std::string& stream_label,
- const std::string& video_track_label,
- const std::string& audio_track_label) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
- mock_dependency_factory_->CreateLocalMediaStream(stream_label));
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> AddRemoteMockMediaStream(
+ const std::string& stream_label,
+ const std::string& video_track_label,
+ const std::string& audio_track_label) {
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
+ mock_dependency_factory_->CreateLocalMediaStream(stream_label).get());
if (!video_track_label.empty()) {
stream->AddTrack(MockWebRtcVideoTrack::Create(video_track_label).get());
}
if (!audio_track_label.empty()) {
stream->AddTrack(MockWebRtcAudioTrack::Create(audio_track_label).get());
}
- mock_peer_connection_->AddRemoteStream(stream.get());
+ mock_peer_connection_->AddRemoteStream(stream);
return stream;
}
@@ -376,18 +376,18 @@ TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(_)).Times(0);
std::string remote_stream_label("remote_stream");
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
EXPECT_CALL(*mock_client_.get(), didRemoveRemoteStream(_)).Times(0);
- pc_handler_->observer()->OnRemoveStream(remote_stream.get());
+ pc_handler_->observer()->OnRemoveStream(remote_stream);
EXPECT_CALL(*mock_client_.get(), didAddRemoteDataChannel(_)).Times(0);
webrtc::DataChannelInit config;
- scoped_refptr<webrtc::DataChannelInterface> remote_data_channel(
+ rtc::scoped_refptr<webrtc::DataChannelInterface> remote_data_channel(
new rtc::RefCountedObject<MockDataChannel>("dummy", &config));
- pc_handler_->observer()->OnDataChannel(remote_data_channel.get());
+ pc_handler_->observer()->OnDataChannel(remote_data_channel);
base::RunLoop().RunUntilIdle();
}
@@ -599,9 +599,9 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
}
TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithRemoteSelector) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
AddRemoteMockMediaStream("remote_stream", "video", "audio"));
- pc_handler_->observer()->OnAddStream(stream.get());
+ pc_handler_->observer()->OnAddStream(stream);
base::RunLoop().RunUntilIdle();
const blink::WebMediaStream& remote_stream = mock_client_->remote_stream();
@@ -781,7 +781,7 @@ TEST_F(RTCPeerConnectionHandlerTest, OnIceGatheringChange) {
TEST_F(RTCPeerConnectionHandlerTest, OnAddAndOnRemoveStream) {
std::string remote_stream_label("remote_stream");
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
testing::InSequence sequence;
@@ -803,23 +803,23 @@ TEST_F(RTCPeerConnectionHandlerTest, OnAddAndOnRemoveStream) {
testing::Property(&blink::WebMediaStream::id,
base::UTF8ToUTF16(remote_stream_label))));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
base::RunLoop().RunUntilIdle();
- pc_handler_->observer()->OnRemoveStream(remote_stream.get());
+ pc_handler_->observer()->OnRemoveStream(remote_stream);
base::RunLoop().RunUntilIdle();
}
// This test that WebKit is notified about remote track state changes.
TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
std::string remote_stream_label("remote_stream");
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
testing::InSequence sequence;
EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(
testing::Property(&blink::WebMediaStream::id,
base::UTF8ToUTF16(remote_stream_label))));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
base::RunLoop().RunUntilIdle();
const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
@@ -859,9 +859,9 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
DoAll(SaveArg<0>(&webkit_stream),
ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
run_loop.Run();
{
@@ -907,9 +907,9 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
DoAll(SaveArg<0>(&webkit_stream),
ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
run_loop.Run();
{
@@ -954,9 +954,9 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddTracksFromRemoteStream) {
DoAll(SaveArg<0>(&webkit_stream),
ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));
- scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
- pc_handler_->observer()->OnAddStream(remote_stream.get());
+ pc_handler_->observer()->OnAddStream(remote_stream);
run_loop.Run();
{
diff --git a/chromium/content/renderer/media/speech_recognition_audio_sink.cc b/chromium/content/renderer/media/speech_recognition_audio_sink.cc
index 08bb010a210..e09431ef4e5 100644
--- a/chromium/content/renderer/media/speech_recognition_audio_sink.cc
+++ b/chromium/content/renderer/media/speech_recognition_audio_sink.cc
@@ -162,7 +162,7 @@ void SpeechRecognitionAudioSink::OnData(
}
double SpeechRecognitionAudioSink::ProvideInput(media::AudioBus* audio_bus,
- base::TimeDelta buffer_delay) {
+ uint32_t frames_delayed) {
DCHECK(capture_thread_checker_.CalledOnValidThread());
if (fifo_->frames() >= audio_bus->frames())
fifo_->Consume(audio_bus, 0, audio_bus->frames());
diff --git a/chromium/content/renderer/media/speech_recognition_audio_sink.h b/chromium/content/renderer/media/speech_recognition_audio_sink.h
index e756638363a..a7fa2800b3a 100644
--- a/chromium/content/renderer/media/speech_recognition_audio_sink.h
+++ b/chromium/content/renderer/media/speech_recognition_audio_sink.h
@@ -62,7 +62,7 @@ class CONTENT_EXPORT SpeechRecognitionAudioSink
// media::AudioConverter::Inputcallback implementation.
double ProvideInput(media::AudioBus* audio_bus,
- base::TimeDelta buffer_delay) override;
+ uint32_t frames_delayed) override;
// Returns the pointer to the audio input buffer mapped in the shared memory.
media::AudioInputBuffer* GetAudioInputBuffer() const;
diff --git a/chromium/content/renderer/media/track_audio_renderer.cc b/chromium/content/renderer/media/track_audio_renderer.cc
index 7cadedc02ce..625a65d127b 100644
--- a/chromium/content/renderer/media/track_audio_renderer.cc
+++ b/chromium/content/renderer/media/track_audio_renderer.cc
@@ -12,8 +12,8 @@
#include "base/trace_event/trace_event.h"
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/media_stream_audio_track.h"
-#include "content/renderer/media/webrtc_audio_renderer.h"
#include "media/base/audio_bus.h"
+#include "media/base/audio_latency.h"
#include "media/base/audio_shifter.h"
namespace content {
@@ -311,7 +311,7 @@ void TrackAudioRenderer::MaybeStartSink() {
media::AudioParameters sink_params(
hardware_params.format(), source_params_.channel_layout(),
source_params_.sample_rate(), source_params_.bits_per_sample(),
- WebRtcAudioRenderer::GetOptimalBufferSize(
+ media::AudioLatency::GetRtcBufferSize(
source_params_.sample_rate(), hardware_params.frames_per_buffer()));
DVLOG(1) << ("TrackAudioRenderer::MaybeStartSink() -- Starting sink. "
"source_params_={")
diff --git a/chromium/content/renderer/media/track_audio_renderer.h b/chromium/content/renderer/media/track_audio_renderer.h
index 43c0d7fa71b..509f31988cc 100644
--- a/chromium/content/renderer/media/track_audio_renderer.h
+++ b/chromium/content/renderer/media/track_audio_renderer.h
@@ -127,7 +127,7 @@ class CONTENT_EXPORT TrackAudioRenderer
// with the audio track.
blink::WebMediaStreamTrack audio_track_;
- // The render view and frame in which the audio is rendered into |sink_|.
+ // The RenderFrame in which the audio is rendered into |sink_|.
const int playout_render_frame_id_;
const int session_id_;
diff --git a/chromium/content/renderer/media/user_media_client_impl.cc b/chromium/content/renderer/media/user_media_client_impl.cc
index 1a8df36355c..cba0545d2d5 100644
--- a/chromium/content/renderer/media/user_media_client_impl.cc
+++ b/chromium/content/renderer/media/user_media_client_impl.cc
@@ -1186,4 +1186,8 @@ bool UserMediaClientImpl::UserMediaRequestInfo::HasPendingSources() const {
return !sources_waiting_for_callback_.empty();
}
+void UserMediaClientImpl::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/user_media_client_impl.h b/chromium/content/renderer/media/user_media_client_impl.h
index f920ca7420d..0b189f52040 100644
--- a/chromium/content/renderer/media/user_media_client_impl.h
+++ b/chromium/content/renderer/media/user_media_client_impl.h
@@ -196,6 +196,9 @@ class CONTENT_EXPORT UserMediaClientImpl
struct MediaDevicesRequestInfo;
typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests;
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Creates a WebKit representation of stream sources based on
// |devices| from the MediaStreamDispatcher.
void InitializeSourceObject(
diff --git a/chromium/content/renderer/media/video_capture_impl.cc b/chromium/content/renderer/media/video_capture_impl.cc
index 90026160a5e..1ccd6c63fce 100644
--- a/chromium/content/renderer/media/video_capture_impl.cc
+++ b/chromium/content/renderer/media/video_capture_impl.cc
@@ -191,7 +191,6 @@ void VideoCaptureImpl::StartCapture(
}
DVLOG(1) << "StartCapture: starting with first resolution "
<< params_.requested_format.frame_size.ToString();
- first_frame_timestamp_ = base::TimeTicks();
StartCaptureInternal();
}
}
@@ -304,7 +303,7 @@ void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) {
void VideoCaptureImpl::OnBufferReceived(
int buffer_id,
- base::TimeTicks timestamp,
+ base::TimeDelta timestamp,
const base::DictionaryValue& metadata,
media::VideoPixelFormat pixel_format,
media::VideoFrame::StorageType storage_type,
@@ -324,14 +323,31 @@ void VideoCaptureImpl::OnBufferReceived(
gpu::SyncToken(), -1.0));
return;
}
- if (first_frame_timestamp_.is_null())
- first_frame_timestamp_ = timestamp;
+ base::TimeTicks reference_time;
+ media::VideoFrameMetadata frame_metadata;
+ frame_metadata.MergeInternalValuesFrom(metadata);
+ const bool success = frame_metadata.GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &reference_time);
+ DCHECK(success);
+
+ if (first_frame_ref_time_.is_null())
+ first_frame_ref_time_ = reference_time;
+
+ // If the timestamp is not prepared, we use reference time to make a rough
+ // estimate. e.g. ThreadSafeCaptureOracle::DidCaptureFrame().
+ // TODO(miu): Fix upstream capturers to always set timestamp and reference
+ // time. See http://crbug/618407/ for tracking.
+ if (timestamp.is_zero())
+ timestamp = reference_time - first_frame_ref_time_;
+
+ // TODO(qiangchen): Change the metric name to "reference_time" and
+ // "timestamp", so that we have consistent naming everywhere.
// Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived",
TRACE_EVENT_SCOPE_THREAD, "timestamp",
- timestamp.ToInternalValue(), "time_delta",
- (timestamp - first_frame_timestamp_).ToInternalValue());
+ (reference_time - base::TimeTicks()).InMicroseconds(),
+ "time_delta", timestamp.InMicroseconds());
scoped_refptr<media::VideoFrame> frame;
BufferFinishedCallback buffer_finished_callback;
@@ -343,11 +359,8 @@ void VideoCaptureImpl::OnBufferReceived(
scoped_refptr<ClientBuffer2> buffer = iter->second;
const auto& handles = buffer->gpu_memory_buffer_handles();
frame = media::VideoFrame::WrapExternalYuvGpuMemoryBuffers(
- media::PIXEL_FORMAT_I420,
- coded_size,
- gfx::Rect(coded_size),
- coded_size,
- buffer->stride(media::VideoFrame::kYPlane),
+ media::PIXEL_FORMAT_I420, coded_size, gfx::Rect(coded_size),
+ coded_size, buffer->stride(media::VideoFrame::kYPlane),
buffer->stride(media::VideoFrame::kUPlane),
buffer->stride(media::VideoFrame::kVPlane),
buffer->data(media::VideoFrame::kYPlane),
@@ -355,8 +368,7 @@ void VideoCaptureImpl::OnBufferReceived(
buffer->data(media::VideoFrame::kVPlane),
handles[media::VideoFrame::kYPlane],
handles[media::VideoFrame::kUPlane],
- handles[media::VideoFrame::kVPlane],
- timestamp - first_frame_timestamp_);
+ handles[media::VideoFrame::kVPlane], timestamp);
buffer_finished_callback = media::BindToCurrentLoop(
base::Bind(&VideoCaptureImpl::OnClientBufferFinished2,
weak_factory_.GetWeakPtr(), buffer_id, buffer));
@@ -371,7 +383,7 @@ void VideoCaptureImpl::OnBufferReceived(
gfx::Size(visible_rect.width(), visible_rect.height()),
reinterpret_cast<uint8_t*>(buffer->buffer()->memory()),
buffer->buffer_size(), buffer->buffer()->handle(),
- 0 /* shared_memory_offset */, timestamp - first_frame_timestamp_);
+ 0 /* shared_memory_offset */, timestamp);
buffer_finished_callback = media::BindToCurrentLoop(
base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
weak_factory_.GetWeakPtr(), buffer_id, buffer));
@@ -387,16 +399,16 @@ void VideoCaptureImpl::OnBufferReceived(
return;
}
- frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
- timestamp);
frame->AddDestructionObserver(
base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(),
base::Passed(&release_sync_token), buffer_finished_callback));
frame->metadata()->MergeInternalValuesFrom(metadata);
+ // TODO(qiangchen): Dive into the full code path to let frame metadata hold
+ // reference time rather than using an extra parameter.
for (const auto& client : clients_)
- client.second.deliver_frame_cb.Run(frame, timestamp);
+ client.second.deliver_frame_cb.Run(frame, reference_time);
}
void VideoCaptureImpl::OnClientBufferFinished(
diff --git a/chromium/content/renderer/media/video_capture_impl.h b/chromium/content/renderer/media/video_capture_impl.h
index b07823486d8..74c4d19d33f 100644
--- a/chromium/content/renderer/media/video_capture_impl.h
+++ b/chromium/content/renderer/media/video_capture_impl.h
@@ -120,14 +120,13 @@ class CONTENT_EXPORT VideoCaptureImpl
const gfx::Size& size,
int buffer_id) override;
void OnBufferDestroyed(int buffer_id) override;
- void OnBufferReceived(
- int buffer_id,
- base::TimeTicks timestamp,
- const base::DictionaryValue& metadata,
- media::VideoPixelFormat pixel_format,
- media::VideoFrame::StorageType storage_type,
- const gfx::Size& coded_size,
- const gfx::Rect& visible_rect) override;
+ void OnBufferReceived(int buffer_id,
+ base::TimeDelta timestamp,
+ const base::DictionaryValue& metadata,
+ media::VideoPixelFormat pixel_format,
+ media::VideoFrame::StorageType storage_type,
+ const gfx::Size& coded_size,
+ const gfx::Rect& visible_rect) override;
void OnStateChanged(VideoCaptureState state) override;
void OnDeviceSupportedFormatsEnumerated(
const media::VideoCaptureFormats& supported_formats) override;
@@ -189,8 +188,9 @@ class CONTENT_EXPORT VideoCaptureImpl
// client to this class via StartCapture().
media::VideoCaptureParams params_;
- // The device's first captured frame timestamp sent from browser process side.
- base::TimeTicks first_frame_timestamp_;
+ // The device's first captured frame referecne time sent from browser process
+ // side.
+ base::TimeTicks first_frame_ref_time_;
bool suspended_;
VideoCaptureState state_;
diff --git a/chromium/content/renderer/media/video_capture_impl_unittest.cc b/chromium/content/renderer/media/video_capture_impl_unittest.cc
index 1fc43c024b8..7ad265e1919 100644
--- a/chromium/content/renderer/media/video_capture_impl_unittest.cc
+++ b/chromium/content/renderer/media/video_capture_impl_unittest.cc
@@ -168,10 +168,18 @@ class VideoCaptureImplTest : public ::testing::Test {
}
void BufferReceived(int buffer_id, const gfx::Size& size) {
+ base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeDelta timestamp = now - base::TimeTicks();
+
+ media::VideoFrameMetadata frame_metadata;
+ frame_metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
+ now);
+ base::DictionaryValue metadata;
+ frame_metadata.MergeInternalValuesInto(&metadata);
+
video_capture_impl_->OnBufferReceived(
- buffer_id, base::TimeTicks::Now(), base::DictionaryValue(),
- media::PIXEL_FORMAT_I420, media::VideoFrame::STORAGE_SHMEM, size,
- gfx::Rect(size));
+ buffer_id, timestamp, metadata, media::PIXEL_FORMAT_I420,
+ media::VideoFrame::STORAGE_SHMEM, size, gfx::Rect(size));
}
void BufferDestroyed(int buffer_id) {
diff --git a/chromium/content/renderer/media/video_capture_message_filter.h b/chromium/content/renderer/media/video_capture_message_filter.h
index 9088cd38f24..05939715957 100644
--- a/chromium/content/renderer/media/video_capture_message_filter.h
+++ b/chromium/content/renderer/media/video_capture_message_filter.h
@@ -48,14 +48,13 @@ class CONTENT_EXPORT VideoCaptureMessageFilter : public IPC::MessageFilter {
// Called when a buffer referencing a captured VideoFrame is received from
// Browser process.
- virtual void OnBufferReceived(
- int buffer_id,
- base::TimeTicks timestamp,
- const base::DictionaryValue& metadata,
- media::VideoPixelFormat pixel_format,
- media::VideoFrame::StorageType storage_type,
- const gfx::Size& coded_size,
- const gfx::Rect& visible_rect) = 0;
+ virtual void OnBufferReceived(int buffer_id,
+ base::TimeDelta timestamp,
+ const base::DictionaryValue& metadata,
+ media::VideoPixelFormat pixel_format,
+ media::VideoFrame::StorageType storage_type,
+ const gfx::Size& coded_size,
+ const gfx::Rect& visible_rect) = 0;
// Called when state of a video capture device has changed in the browser
// process.
diff --git a/chromium/content/renderer/media/video_capture_message_filter_unittest.cc b/chromium/content/renderer/media/video_capture_message_filter_unittest.cc
index 6a339404de1..05845bf3232 100644
--- a/chromium/content/renderer/media/video_capture_message_filter_unittest.cc
+++ b/chromium/content/renderer/media/video_capture_message_filter_unittest.cc
@@ -43,7 +43,7 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate {
MOCK_METHOD1(OnBufferDestroyed, void(int buffer_id));
MOCK_METHOD7(OnBufferReceived,
void(int buffer_id,
- base::TimeTicks timestamp,
+ base::TimeDelta timestamp,
const base::DictionaryValue& metadata,
media::VideoPixelFormat pixel_format,
media::VideoFrame::StorageType storage_type,
@@ -122,8 +122,12 @@ TEST(VideoCaptureMessageFilterTest, Basic) {
VideoCaptureMsg_BufferReady_Params params;
params.device_id = delegate.device_id();
params.buffer_id = 22;
- params.timestamp = base::TimeTicks::FromInternalValue(1);
+ params.timestamp = base::TimeDelta::FromMicroseconds(1);
params.metadata.SetString("foo", "bar");
+ media::VideoFrameMetadata frame_metadata;
+ frame_metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
+ base::TimeTicks::FromInternalValue(1));
+ frame_metadata.MergeInternalValuesInto(&params.metadata);
params.pixel_format = media::PIXEL_FORMAT_I420;
params.storage_type = media::VideoFrame::STORAGE_SHMEM;
params.coded_size = gfx::Size(234, 512);
diff --git a/chromium/content/renderer/media/video_track_recorder.cc b/chromium/content/renderer/media/video_track_recorder.cc
index 8da8f308492..d65e238e879 100644
--- a/chromium/content/renderer/media/video_track_recorder.cc
+++ b/chromium/content/renderer/media/video_track_recorder.cc
@@ -10,11 +10,17 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/sys_info.h"
+#include "base/task_runner_util.h"
#include "base/threading/thread.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
+#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
+#include "content/renderer/render_thread_impl.h"
+#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(RTC_USE_H264)
@@ -36,6 +42,62 @@ using media::VideoFrameMetadata;
namespace content {
+namespace {
+
+const int kVEAEncoderMinResolutionWidth = 640;
+const int kVEAEncoderMinResolutionHeight = 480;
+const int kVEAEncoderOutputBufferCount = 4;
+
+static struct {
+ VideoTrackRecorder::CodecId codec_id;
+ media::VideoCodecProfile min_profile;
+ media::VideoCodecProfile max_profile;
+} const kSupportedVideoCodecIdToProfile[] = {
+ {VideoTrackRecorder::CodecId::VP8,
+ media::VP8PROFILE_MIN,
+ media::VP8PROFILE_MAX},
+ {VideoTrackRecorder::CodecId::VP9,
+ media::VP9PROFILE_MIN,
+ media::VP9PROFILE_MAX},
+ {VideoTrackRecorder::CodecId::H264,
+ media::H264PROFILE_MIN,
+ media::H264PROFILE_MAX}};
+
+// Returns the corresponding codec profile from VEA supported codecs. If no
+// profile is found, returns VIDEO_CODEC_PROFILE_UNKNOWN.
+media::VideoCodecProfile CodecIdToVEAProfile(
+ content::VideoTrackRecorder::CodecId codec) {
+ // See https://crbug.com/616659.
+#if defined(OS_CHROMEOS)
+ return media::VIDEO_CODEC_PROFILE_UNKNOWN;
+#endif // defined(OS_CHROMEOS)
+ content::RenderThreadImpl* render_thread_impl =
+ content::RenderThreadImpl::current();
+ if (!render_thread_impl)
+ return media::VIDEO_CODEC_PROFILE_UNKNOWN;
+
+ media::GpuVideoAcceleratorFactories* gpu_factories =
+ content::RenderThreadImpl::current()->GetGpuFactories();
+ if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) {
+ DVLOG(3) << "Couldn't initialize GpuVideoAcceleratorFactories";
+ return media::VIDEO_CODEC_PROFILE_UNKNOWN;
+ }
+
+ const media::VideoEncodeAccelerator::SupportedProfiles& vea_profiles =
+ gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
+ for (const auto& vea_profile : vea_profiles) {
+ for (const auto& supported_profile : kSupportedVideoCodecIdToProfile) {
+ if (codec == supported_profile.codec_id &&
+ vea_profile.profile >= supported_profile.min_profile &&
+ vea_profile.profile <= supported_profile.max_profile)
+ return vea_profile.profile;
+ }
+ }
+ return media::VIDEO_CODEC_PROFILE_UNKNOWN;
+}
+
+} // anonymous namespace
+
// Base class to describe a generic Encoder, encapsulating all actual encoder
// (re)configurations, encoding and delivery of received frames. This class is
// ref-counted to allow the MediaStreamVideoTrack to hold a reference to it (via
@@ -56,13 +118,13 @@ class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> {
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner =
nullptr)
- : main_task_runner_(base::MessageLoop::current()->task_runner()),
+ : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
encoding_task_runner_(encoding_task_runner),
paused_(false),
on_encoded_video_callback_(on_encoded_video_callback),
bits_per_second_(bits_per_second) {
DCHECK(!on_encoded_video_callback_.is_null());
- if (encoding_thread_)
+ if (encoding_task_runner_)
return;
encoding_thread_.reset(new base::Thread("EncodingThread"));
encoding_thread_->Start();
@@ -116,7 +178,7 @@ void VideoTrackRecorder::Encoder::StartFrameEncode(
base::TimeTicks capture_timestamp) {
// Cache the thread sending frames on first frame arrival.
if (!origin_task_runner_.get())
- origin_task_runner_ = base::MessageLoop::current()->task_runner();
+ origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
DCHECK(origin_task_runner_->BelongsToCurrentThread());
if (paused_)
return;
@@ -179,6 +241,69 @@ static int GetNumberOfThreadsForEncoding() {
return std::min(8, (base::SysInfo::NumberOfProcessors() + 1) / 2);
}
+// Class encapsulating VideoEncodeAccelerator interactions.
+// This class is created and destroyed in its owner thread. All other methods
+// operate on the task runner pointed by GpuFactories.
+class VEAEncoder final : public VideoTrackRecorder::Encoder,
+ public media::VideoEncodeAccelerator::Client {
+ public:
+ VEAEncoder(
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
+ int32_t bits_per_second,
+ media::VideoCodecProfile codec);
+
+ // media::VideoEncodeAccelerator::Client implementation.
+ void RequireBitstreamBuffers(unsigned int input_count,
+ const gfx::Size& input_coded_size,
+ size_t output_buffer_size) override;
+ void BitstreamBufferReady(int32_t bitstream_buffer_id,
+ size_t payload_size,
+ bool key_frame,
+ base::TimeDelta timestamp) override;
+ void NotifyError(media::VideoEncodeAccelerator::Error error) override;
+
+ private:
+ using VideoFrameAndTimestamp =
+ std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>;
+
+ void UseOutputBitstreamBufferId(int32_t bitstream_buffer_id);
+ void FrameFinished(std::unique_ptr<base::SharedMemory> shm);
+
+ // VideoTrackRecorder::Encoder implementation.
+ ~VEAEncoder() override;
+ void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
+ base::TimeTicks capture_timestamp) override;
+ void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) override;
+
+ media::GpuVideoAcceleratorFactories* const gpu_factories_;
+
+ const media::VideoCodecProfile codec_;
+
+ // The underlying VEA to perform encoding on.
+ std::unique_ptr<media::VideoEncodeAccelerator> video_encoder_;
+
+ // Shared memory buffers for output with the VEA.
+ std::vector<std::unique_ptr<base::SharedMemory>> output_buffers_;
+
+ // Shared memory buffers for output with the VEA as FIFO.
+ std::queue<std::unique_ptr<base::SharedMemory>> input_buffers_;
+
+ // Tracks error status.
+ bool error_notified_;
+
+ // Tracks the first frame to encode.
+ std::unique_ptr<VideoFrameAndTimestamp> first_frame_;
+
+ // Size used to initialize encoder.
+ gfx::Size input_size_;
+
+ // Coded size that encoder requests as input.
+ gfx::Size vea_requested_input_size_;
+
+ // Frames and corresponding timestamps in encode as FIFO.
+ std::queue<VideoFrameAndTimestamp> frames_in_encode_;
+};
+
// Class encapsulating all libvpx interactions for VP8/VP9 encoding.
class VpxEncoder final : public VideoTrackRecorder::Encoder {
public:
@@ -191,10 +316,10 @@ class VpxEncoder final : public VideoTrackRecorder::Encoder {
int32_t bits_per_second);
private:
- // VideoTrackRecorder::Encoder
+ // VideoTrackRecorder::Encoder implementation.
~VpxEncoder() override;
void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
- base::TimeTicks capture_timestamp) override;
+ base::TimeTicks capture_timestamp) override;
void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) override;
// Returns true if |codec_config_| has been filled in at least once.
@@ -243,7 +368,7 @@ class H264Encoder final : public VideoTrackRecorder::Encoder {
int32_t bits_per_second);
private:
- // VideoTrackRecorder::Encoder
+ // VideoTrackRecorder::Encoder implementation.
~H264Encoder() override;
void EncodeOnEncodingTaskRunner(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks capture_timestamp) override;
@@ -264,6 +389,196 @@ class H264Encoder final : public VideoTrackRecorder::Encoder {
#endif // #if BUILDFLAG(RTC_USE_H264)
+VEAEncoder::VEAEncoder(
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
+ int32_t bits_per_second,
+ media::VideoCodecProfile codec)
+ : Encoder(on_encoded_video_callback,
+ bits_per_second,
+ RenderThreadImpl::current()->GetGpuFactories()->GetTaskRunner()),
+ gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()),
+ codec_(codec),
+ error_notified_(false) {
+ DCHECK(gpu_factories_);
+}
+
+VEAEncoder::~VEAEncoder() {
+ encoding_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&media::VideoEncodeAccelerator::Destroy,
+ base::Unretained(video_encoder_.release())));
+}
+
+void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/,
+ const gfx::Size& input_coded_size,
+ size_t output_buffer_size) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+
+ vea_requested_input_size_ = input_coded_size;
+ output_buffers_.clear();
+ std::queue<std::unique_ptr<base::SharedMemory>>().swap(input_buffers_);
+
+ for (int i = 0; i < kVEAEncoderOutputBufferCount; ++i) {
+ std::unique_ptr<base::SharedMemory> shm =
+ gpu_factories_->CreateSharedMemory(output_buffer_size);
+ if (shm)
+ output_buffers_.push_back(base::WrapUnique(shm.release()));
+ }
+
+ for (size_t i = 0; i < output_buffers_.size(); ++i)
+ UseOutputBitstreamBufferId(i);
+}
+
+void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id,
+ size_t payload_size,
+ bool keyframe,
+ base::TimeDelta timestamp) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+
+ base::SharedMemory* output_buffer =
+ output_buffers_[bitstream_buffer_id].get();
+
+ std::unique_ptr<std::string> data(new std::string);
+ data->append(reinterpret_cast<char*>(output_buffer->memory()), payload_size);
+
+ const auto front_frame = frames_in_encode_.front();
+ frames_in_encode_.pop();
+ origin_task_runner_->PostTask(
+ FROM_HERE, base::Bind(OnFrameEncodeCompleted, on_encoded_video_callback_,
+ front_frame.first, base::Passed(&data),
+ front_frame.second, keyframe));
+ UseOutputBitstreamBufferId(bitstream_buffer_id);
+}
+
+void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+
+ // TODO(emircan): Notify the owner via a callback.
+ error_notified_ = true;
+}
+
+void VEAEncoder::UseOutputBitstreamBufferId(int32_t bitstream_buffer_id) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+
+ video_encoder_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
+ bitstream_buffer_id, output_buffers_[bitstream_buffer_id]->handle(),
+ output_buffers_[bitstream_buffer_id]->mapped_size()));
+}
+
+void VEAEncoder::FrameFinished(std::unique_ptr<base::SharedMemory> shm) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+ input_buffers_.push(std::move(shm));
+}
+
+void VEAEncoder::EncodeOnEncodingTaskRunner(
+ const scoped_refptr<VideoFrame>& frame,
+ base::TimeTicks capture_timestamp) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+
+ if (input_size_ != frame->visible_rect().size() && video_encoder_) {
+ video_encoder_->Destroy();
+ video_encoder_.reset();
+ }
+
+ if (!video_encoder_) {
+ ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size());
+ first_frame_.reset(
+ new std::pair<scoped_refptr<VideoFrame>, base::TimeTicks>(
+ frame, capture_timestamp));
+ }
+
+ if (error_notified_) {
+ DVLOG(3) << "An error occurred in VEA encoder";
+ return;
+ }
+
+ // Drop frames if there is no output buffers available.
+ if (output_buffers_.empty()) {
+ // TODO(emircan): Investigate if resetting encoder would help.
+ DVLOG(3) << "Dropped frame.";
+ return;
+ }
+
+ // If first frame hasn't been encoded, do it first.
+ if (first_frame_) {
+ std::unique_ptr<VideoFrameAndTimestamp> first_frame(first_frame_.release());
+ EncodeOnEncodingTaskRunner(first_frame->first, first_frame->second);
+ }
+
+ // Lower resolutions may fall back to SW encoder in some platforms, i.e. Mac.
+ // In that case, the encoder expects more frames before returning result.
+ // Therefore, a copy is necessary to release the current frame.
+ scoped_refptr<media::VideoFrame> video_frame = frame;
+ if (vea_requested_input_size_ != input_size_ ||
+ input_size_.width() < kVEAEncoderMinResolutionWidth ||
+ input_size_.height() < kVEAEncoderMinResolutionHeight) {
+ // Create SharedMemory backed input buffers as necessary. These SharedMemory
+ // instances will be shared with GPU process.
+ std::unique_ptr<base::SharedMemory> input_buffer;
+ const size_t desired_mapped_size = media::VideoFrame::AllocationSize(
+ media::PIXEL_FORMAT_I420, vea_requested_input_size_);
+ if (input_buffers_.empty()) {
+ input_buffer = gpu_factories_->CreateSharedMemory(desired_mapped_size);
+ } else {
+ do {
+ input_buffer = std::move(input_buffers_.front());
+ input_buffers_.pop();
+ } while (!input_buffers_.empty() &&
+ input_buffer->mapped_size() < desired_mapped_size);
+ if (!input_buffer || input_buffer->mapped_size() < desired_mapped_size)
+ return;
+ }
+
+ video_frame = media::VideoFrame::WrapExternalSharedMemory(
+ media::PIXEL_FORMAT_I420, vea_requested_input_size_,
+ gfx::Rect(input_size_), input_size_,
+ reinterpret_cast<uint8_t*>(input_buffer->memory()),
+ input_buffer->mapped_size(), input_buffer->handle(), 0,
+ frame->timestamp());
+ video_frame->AddDestructionObserver(media::BindToCurrentLoop(
+ base::Bind(&VEAEncoder::FrameFinished, this,
+ base::Passed(std::move(input_buffer)))));
+ libyuv::I420Copy(frame->visible_data(media::VideoFrame::kYPlane),
+ frame->stride(media::VideoFrame::kYPlane),
+ frame->visible_data(media::VideoFrame::kUPlane),
+ frame->stride(media::VideoFrame::kUPlane),
+ frame->visible_data(media::VideoFrame::kVPlane),
+ frame->stride(media::VideoFrame::kVPlane),
+ video_frame->visible_data(media::VideoFrame::kYPlane),
+ video_frame->stride(media::VideoFrame::kYPlane),
+ video_frame->visible_data(media::VideoFrame::kUPlane),
+ video_frame->stride(media::VideoFrame::kUPlane),
+ video_frame->visible_data(media::VideoFrame::kVPlane),
+ video_frame->stride(media::VideoFrame::kVPlane),
+ input_size_.width(), input_size_.height());
+ }
+ frames_in_encode_.push(std::make_pair(video_frame, capture_timestamp));
+
+ encoding_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&media::VideoEncodeAccelerator::Encode,
+ base::Unretained(video_encoder_.get()), video_frame, false));
+}
+
+void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) {
+ DVLOG(3) << __FUNCTION__;
+ DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+ DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread());
+
+ input_size_ = size;
+ video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator();
+ if (!video_encoder_ ||
+ !video_encoder_->Initialize(media::PIXEL_FORMAT_I420, input_size_, codec_,
+ bits_per_second_, this)) {
+ NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
+ }
+}
+
// static
void VpxEncoder::ShutdownEncoder(std::unique_ptr<base::Thread> encoding_thread,
ScopedVpxCodecCtxPtr encoder) {
@@ -624,21 +939,28 @@ VideoTrackRecorder::VideoTrackRecorder(
: track_(track) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(!track_.isNull());
- DCHECK(track_.getExtraData());
+ DCHECK(track_.getTrackData());
- switch (codec) {
+ const auto& vea_supported_profile = CodecIdToVEAProfile(codec);
+ // TODO(emircan): Prioritize software based encoders in lower resolutions.
+ if (vea_supported_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN) {
+ encoder_ = new VEAEncoder(on_encoded_video_callback, bits_per_second,
+ vea_supported_profile);
+ } else {
+ switch (codec) {
#if BUILDFLAG(RTC_USE_H264)
- case CodecId::H264:
- encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second);
- break;
+ case CodecId::H264:
+ encoder_ = new H264Encoder(on_encoded_video_callback, bits_per_second);
+ break;
#endif
- case CodecId::VP8:
- case CodecId::VP9:
- encoder_ = new VpxEncoder(codec == CodecId::VP9,
- on_encoded_video_callback, bits_per_second);
- break;
- default:
- NOTREACHED() << "Unsupported codec";
+ case CodecId::VP8:
+ case CodecId::VP9:
+ encoder_ = new VpxEncoder(codec == CodecId::VP9,
+ on_encoded_video_callback, bits_per_second);
+ break;
+ default:
+ NOTREACHED() << "Unsupported codec";
+ }
}
// StartFrameEncode() will be called on Render IO thread.
diff --git a/chromium/content/renderer/media/video_track_recorder.h b/chromium/content/renderer/media/video_track_recorder.h
index a49733f9d70..5e624549224 100644
--- a/chromium/content/renderer/media/video_track_recorder.h
+++ b/chromium/content/renderer/media/video_track_recorder.h
@@ -32,9 +32,7 @@ class CONTENT_EXPORT VideoTrackRecorder
enum class CodecId {
VP8,
VP9,
-#if BUILDFLAG(RTC_USE_H264)
H264,
-#endif
};
class Encoder;
diff --git a/chromium/content/renderer/media/video_track_recorder_unittest.cc b/chromium/content/renderer/media/video_track_recorder_unittest.cc
index 0ca52bb3397..a8390825af8 100644
--- a/chromium/content/renderer/media/video_track_recorder_unittest.cc
+++ b/chromium/content/renderer/media/video_track_recorder_unittest.cc
@@ -65,7 +65,7 @@ class VideoTrackRecorderTest
track_ = new MediaStreamVideoTrack(mock_source_, constraints,
MediaStreamSource::ConstraintsCallback(),
true /* enabled */);
- blink_track_.setExtraData(track_);
+ blink_track_.setTrackData(track_);
video_track_recorder_.reset(new VideoTrackRecorder(
GetParam() /* codec */, blink_track_,
diff --git a/chromium/content/renderer/media/webmediaplayer_ms.cc b/chromium/content/renderer/media/webmediaplayer_ms.cc
index 489d65bc707..d437247d180 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms.cc
@@ -18,7 +18,7 @@
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/public/renderer/media_stream_audio_renderer.h"
#include "content/public/renderer/media_stream_renderer_factory.h"
-#include "content/public/renderer/video_frame_provider.h"
+#include "content/public/renderer/media_stream_video_renderer.h"
#include "content/renderer/media/web_media_element_source_utils.h"
#include "content/renderer/media/webmediaplayer_ms_compositor.h"
#include "content/renderer/render_frame_impl.h"
@@ -124,7 +124,7 @@ void WebMediaPlayerMS::load(LoadType load_type,
web_stream.isNull() ? std::string() : web_stream.id().utf8();
media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id));
- video_frame_provider_ = renderer_factory_->GetVideoFrameProvider(
+ video_frame_provider_ = renderer_factory_->GetVideoRenderer(
web_stream, base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()),
media_task_runner_, worker_task_runner_, gpu_factories_);
@@ -168,7 +168,7 @@ void WebMediaPlayerMS::play() {
return;
if (video_frame_provider_)
- video_frame_provider_->Play();
+ video_frame_provider_->Resume();
compositor_->StartRendering();
diff --git a/chromium/content/renderer/media/webmediaplayer_ms.h b/chromium/content/renderer/media/webmediaplayer_ms.h
index 76b8da1991a..51d116099d7 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms.h
+++ b/chromium/content/renderer/media/webmediaplayer_ms.h
@@ -45,7 +45,7 @@ class GLES2Interface;
namespace content {
class MediaStreamAudioRenderer;
class MediaStreamRendererFactory;
-class VideoFrameProvider;
+class MediaStreamVideoRenderer;
class WebMediaPlayerMSCompositor;
class RenderFrameObserver;
@@ -57,7 +57,7 @@ class RenderFrameObserver;
//
// WebMediaPlayerMS works with multiple objects, the most important ones are:
//
-// VideoFrameProvider
+// MediaStreamVideoRenderer
// provides video frames for rendering.
//
// blink::WebMediaPlayerClient
@@ -68,7 +68,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
public NON_EXPORTED_BASE(base::SupportsWeakPtr<WebMediaPlayerMS>) {
public:
// Construct a WebMediaPlayerMS with reference to the client, and
- // a MediaStreamClient which provides VideoFrameProvider.
+ // a MediaStreamClient which provides MediaStreamVideoRenderer.
WebMediaPlayerMS(
blink::WebFrame* frame,
blink::WebMediaPlayerClient* client,
@@ -161,7 +161,8 @@ class CONTENT_EXPORT WebMediaPlayerMS
private:
friend class WebMediaPlayerMSTest;
- // The callback for VideoFrameProvider to signal a new frame is available.
+ // The callback for MediaStreamVideoRenderer to signal a new frame is
+ // available.
void OnFrameAvailable(const scoped_refptr<media::VideoFrame>& frame);
// Need repaint due to state change.
void RepaintInternal();
@@ -193,12 +194,11 @@ class CONTENT_EXPORT WebMediaPlayerMS
const base::WeakPtr<media::WebMediaPlayerDelegate> delegate_;
int delegate_id_;
- // Specify content:: to disambiguate from cc::.
- scoped_refptr<content::VideoFrameProvider> video_frame_provider_; // Weak
+ scoped_refptr<MediaStreamVideoRenderer> video_frame_provider_; // Weak
std::unique_ptr<cc_blink::WebLayerImpl> video_weblayer_;
- scoped_refptr<MediaStreamAudioRenderer> audio_renderer_; // Weak
+ scoped_refptr<MediaStreamAudioRenderer> audio_renderer_; // Weak
media::SkCanvasVideoRenderer video_renderer_;
bool paused_;
diff --git a/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc b/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
index 37078750f50..d02bb0d1ec5 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms_unittest.cc
@@ -112,13 +112,13 @@ class ReusableMessageLoopEvent {
};
// The class is used mainly to inject VideoFrames into WebMediaPlayerMS.
-class MockVideoFrameProvider : public VideoFrameProvider {
+class MockMediaStreamVideoRenderer : public MediaStreamVideoRenderer {
public:
- MockVideoFrameProvider(
+ MockMediaStreamVideoRenderer(
const scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ReusableMessageLoopEvent* message_loop_controller,
const base::Closure& error_cb,
- const VideoFrameProvider::RepaintCB& repaint_cb)
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb)
: started_(false),
task_runner_(task_runner),
message_loop_controller_(message_loop_controller),
@@ -127,10 +127,10 @@ class MockVideoFrameProvider : public VideoFrameProvider {
delay_till_next_generated_frame_(
base::TimeDelta::FromSecondsD(1.0 / 30.0)) {}
- // Implementation of VideoFrameProvider
+ // Implementation of MediaStreamVideoRenderer
void Start() override;
void Stop() override;
- void Play() override;
+ void Resume() override;
void Pause() override;
// Methods for test use
@@ -142,7 +142,7 @@ class MockVideoFrameProvider : public VideoFrameProvider {
bool Paused() { return paused_; }
private:
- ~MockVideoFrameProvider() override {}
+ ~MockMediaStreamVideoRenderer() override {}
// Main function that pushes a frame into WebMediaPlayerMS
void InjectFrame();
@@ -157,42 +157,43 @@ class MockVideoFrameProvider : public VideoFrameProvider {
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
ReusableMessageLoopEvent* const message_loop_controller_;
const base::Closure error_cb_;
- const VideoFrameProvider::RepaintCB repaint_cb_;
+ const MediaStreamVideoRenderer::RepaintCB repaint_cb_;
std::deque<TestFrame> frames_;
base::TimeDelta delay_till_next_generated_frame_;
};
-void MockVideoFrameProvider::Start() {
+void MockMediaStreamVideoRenderer::Start() {
started_ = true;
paused_ = false;
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&MockVideoFrameProvider::InjectFrame, base::Unretained(this)));
+ base::Bind(&MockMediaStreamVideoRenderer::InjectFrame,
+ base::Unretained(this)));
}
-void MockVideoFrameProvider::Stop() {
+void MockMediaStreamVideoRenderer::Stop() {
started_ = false;
frames_.clear();
}
-void MockVideoFrameProvider::Play() {
+void MockMediaStreamVideoRenderer::Resume() {
CHECK(started_);
paused_ = false;
}
-void MockVideoFrameProvider::Pause() {
+void MockMediaStreamVideoRenderer::Pause() {
CHECK(started_);
paused_ = true;
}
-void MockVideoFrameProvider::AddFrame(
+void MockMediaStreamVideoRenderer::AddFrame(
FrameType category,
const scoped_refptr<media::VideoFrame>& frame) {
frames_.push_back(std::make_pair(category, frame));
}
-void MockVideoFrameProvider::QueueFrames(
+void MockMediaStreamVideoRenderer::QueueFrames(
const std::vector<int>& timestamp_or_frame_type,
bool opaque_frame,
bool odd_size_frame,
@@ -236,7 +237,7 @@ void MockVideoFrameProvider::QueueFrames(
}
}
-void MockVideoFrameProvider::InjectFrame() {
+void MockMediaStreamVideoRenderer::InjectFrame() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (!started_)
return;
@@ -272,7 +273,8 @@ void MockVideoFrameProvider::InjectFrame() {
task_runner_->PostDelayedTask(
FROM_HERE,
- base::Bind(&MockVideoFrameProvider::InjectFrame, base::Unretained(this)),
+ base::Bind(&MockMediaStreamVideoRenderer::InjectFrame,
+ base::Unretained(this)),
delay_till_next_generated_frame_);
// This will pause the |message_loop_|, and the purpose is to allow the main
@@ -293,16 +295,16 @@ class MockRenderFactory : public MediaStreamRendererFactory {
: task_runner_(task_runner),
message_loop_controller_(message_loop_controller) {}
- scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
+ scoped_refptr<MediaStreamVideoRenderer> GetVideoRenderer(
const blink::WebMediaStream& web_stream,
const base::Closure& error_cb,
- const VideoFrameProvider::RepaintCB& repaint_cb,
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories) override;
- MockVideoFrameProvider* provider() {
- return static_cast<MockVideoFrameProvider*>(provider_.get());
+ MockMediaStreamVideoRenderer* provider() {
+ return static_cast<MockMediaStreamVideoRenderer*>(provider_.get());
}
scoped_refptr<MediaStreamAudioRenderer> GetAudioRenderer(
@@ -315,19 +317,19 @@ class MockRenderFactory : public MediaStreamRendererFactory {
private:
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- scoped_refptr<VideoFrameProvider> provider_;
+ scoped_refptr<MediaStreamVideoRenderer> provider_;
ReusableMessageLoopEvent* const message_loop_controller_;
};
-scoped_refptr<VideoFrameProvider> MockRenderFactory::GetVideoFrameProvider(
+scoped_refptr<MediaStreamVideoRenderer> MockRenderFactory::GetVideoRenderer(
const blink::WebMediaStream& web_stream,
const base::Closure& error_cb,
- const VideoFrameProvider::RepaintCB& repaint_cb,
+ const MediaStreamVideoRenderer::RepaintCB& repaint_cb,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::TaskRunner>& worker_task_runner,
media::GpuVideoAcceleratorFactories* gpu_factories) {
- provider_ = new MockVideoFrameProvider(task_runner_, message_loop_controller_,
- error_cb, repaint_cb);
+ provider_ = new MockMediaStreamVideoRenderer(task_runner_,
+ message_loop_controller_, error_cb, repaint_cb);
return provider_;
}
@@ -335,8 +337,8 @@ scoped_refptr<VideoFrameProvider> MockRenderFactory::GetVideoFrameProvider(
// This is the main class coordinating the tests.
// Basic workflow:
// 1. WebMediaPlayerMS::Load will generate and start
-// content::VideoFrameProvider.
-// 2. content::VideoFrameProvider will start pushing frames into
+// content::MediaStreamVideoRenderer.
+// 2. content::MediaStreamVideoRenderer will start pushing frames into
// WebMediaPlayerMS repeatedly.
// 3. On WebMediaPlayerMS receiving the first frame, a WebLayer will be created.
// 4. The WebLayer will call
@@ -346,7 +348,7 @@ scoped_refptr<VideoFrameProvider> MockRenderFactory::GetVideoFrameProvider(
// WebMediaPlayerMSCompositor::UpdateCurrentFrame, GetCurrentFrame for
// rendering repeatedly.
// 6. When WebMediaPlayerMS::pause gets called, it should trigger
-// content::VideoFrameProvider::Pause, and then the provider will stop
+// content::MediaStreamVideoRenderer::Pause, and then the provider will stop
// pushing frames into WebMediaPlayerMS, but instead digesting them;
// simultanously, it should call cc::VideoFrameProviderClient::StopRendering,
// so cc::VideoFrameProviderClient will stop asking frames from
@@ -380,7 +382,7 @@ class WebMediaPlayerMSTest
base::RunLoop().RunUntilIdle();
}
- MockVideoFrameProvider* LoadAndGetFrameProvider(bool algorithm_enabled);
+ MockMediaStreamVideoRenderer* LoadAndGetFrameProvider(bool algorithm_enabled);
// Implementation of WebMediaPlayerClient
void networkStateChanged() override;
@@ -396,7 +398,7 @@ class WebMediaPlayerMSTest
const blink::WebString& label,
const blink::WebString& language,
bool enabled) override {
- return 0;
+ return blink::WebMediaPlayer::TrackId();
}
void removeAudioTrack(blink::WebMediaPlayer::TrackId) override {}
blink::WebMediaPlayer::TrackId addVideoTrack(const blink::WebString& id,
@@ -404,7 +406,7 @@ class WebMediaPlayerMSTest
const blink::WebString& label,
const blink::WebString& language,
bool selected) override {
- return 0;
+ return blink::WebMediaPlayer::TrackId();
}
void removeVideoTrack(blink::WebMediaPlayer::TrackId) override {}
void addTextTrack(blink::WebInbandTextTrack*) override {}
@@ -454,7 +456,7 @@ class WebMediaPlayerMSTest
bool background_rendering_;
};
-MockVideoFrameProvider* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
+MockMediaStreamVideoRenderer* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
bool algorithm_enabled) {
EXPECT_FALSE(!!render_factory_->provider()) << "There should not be a "
"FrameProvider yet.";
@@ -470,7 +472,7 @@ MockVideoFrameProvider* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
EXPECT_TRUE(!!compositor_);
compositor_->SetAlgorithmEnabledForTesting(algorithm_enabled);
- MockVideoFrameProvider* const provider = render_factory_->provider();
+ MockMediaStreamVideoRenderer* const provider = render_factory_->provider();
EXPECT_TRUE(!!provider);
EXPECT_TRUE(provider->Started());
@@ -556,7 +558,7 @@ TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
// and verifies that they are produced by WebMediaPlayerMS in appropriate
// order.
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
333, 366, 400, 433, 466, 500, 533, 566, 600};
@@ -583,7 +585,7 @@ TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
// This tests sends a broken frame to WebMediaPlayerMS, and verifies
// OnSourceError function works as expected.
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
const int kBrokenFrame = static_cast<int>(FrameType::BROKEN_FRAME);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
@@ -615,7 +617,7 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
// In the middle of this test, WebMediaPlayerMS::pause will be called, and we
// are going to verify that during the pause stage, a frame gets freezed, and
// cc::VideoFrameProviderClient should also be paused.
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166, 200, 233, 266,
@@ -655,7 +657,7 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
const bool odd_size_frame = testing::get<1>(GetParam());
// Similary to PlayAndPause test above, this one focuses on testing that
// WebMediaPlayerMS can be resumed after a period of paused status.
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(false);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166,
@@ -714,7 +716,7 @@ TEST_F(WebMediaPlayerMSTest, BackgroundRendering) {
// WebMediaPlayerMS without an explicit notification. We should expect that
// WebMediaPlayerMS can digest old frames, rather than piling frames up and
// explode.
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
int tokens[] = {0, 33, 66, 100, 133, kTestBrake, 166,
@@ -760,7 +762,7 @@ TEST_F(WebMediaPlayerMSTest, FrameSizeChange) {
// During this test, the frame size of the input changes.
// We need to make sure, when sizeChanged() gets called, new size should be
// returned by GetCurrentSize().
- MockVideoFrameProvider* provider = LoadAndGetFrameProvider(true);
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
333, 366, 400, 433, 466, 500, 533, 566, 600};
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
index 928b1804c68..78ac79672cf 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -72,6 +72,10 @@ MediaStreamRemoteVideoSource::
RemoteVideoSourceDelegate::~RemoteVideoSourceDelegate() {
}
+namespace {
+void DoNothing(const scoped_refptr<rtc::RefCountInterface>& ref) {}
+} // anonymous
+
void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
const cricket::VideoFrame& incoming_frame) {
const base::TimeDelta incoming_timestamp = base::TimeDelta::FromMicroseconds(
@@ -89,16 +93,19 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
incoming_timestamp - start_timestamp_;
scoped_refptr<media::VideoFrame> video_frame;
- if (incoming_frame.video_frame_buffer()->native_handle() != NULL) {
+ scoped_refptr<webrtc::VideoFrameBuffer> buffer(
+ incoming_frame.video_frame_buffer());
+
+ if (buffer->native_handle() != NULL) {
video_frame =
- static_cast<media::VideoFrame*>(
- incoming_frame.video_frame_buffer()->native_handle());
+ static_cast<media::VideoFrame*>(buffer->native_handle());
video_frame->set_timestamp(elapsed_timestamp);
} else {
- const cricket::VideoFrame* frame =
- incoming_frame.GetCopyWithRotationApplied();
-
- gfx::Size size(frame->width(), frame->height());
+ // Note that the GetCopyWithRotationApplied returns a pointer to a
+ // frame owned by incoming_frame.
+ buffer =
+ incoming_frame.GetCopyWithRotationApplied()->video_frame_buffer();
+ gfx::Size size(buffer->width(), buffer->height());
// Make a shallow copy. Both |frame| and |video_frame| will share a single
// reference counted frame buffer. Const cast and hope no one will overwrite
@@ -107,17 +114,17 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
// need to const cast here.
video_frame = media::VideoFrame::WrapExternalYuvData(
media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size,
- frame->video_frame_buffer()->StrideY(),
- frame->video_frame_buffer()->StrideU(),
- frame->video_frame_buffer()->StrideV(),
- const_cast<uint8_t*>(frame->video_frame_buffer()->DataY()),
- const_cast<uint8_t*>(frame->video_frame_buffer()->DataU()),
- const_cast<uint8_t*>(frame->video_frame_buffer()->DataV()),
+ buffer->StrideY(),
+ buffer->StrideU(),
+ buffer->StrideV(),
+ const_cast<uint8_t*>(buffer->DataY()),
+ const_cast<uint8_t*>(buffer->DataU()),
+ const_cast<uint8_t*>(buffer->DataV()),
elapsed_timestamp);
if (!video_frame)
return;
- video_frame->AddDestructionObserver(
- base::Bind(&base::DeletePointer<cricket::VideoFrame>, frame->Copy()));
+ // The bind ensures that we keep a reference to the underlying buffer.
+ video_frame->AddDestructionObserver(base::Bind(&DoNothing, buffer));
}
video_frame->metadata()->SetTimeTicks(
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
index 5cd94260e38..b921adb8422 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -128,9 +128,13 @@ TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
base::Closure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(sink, OnVideoFrame()).WillOnce(
RunClosure(quit_closure));
- cricket::WebRtcVideoFrame webrtc_frame;
- webrtc_frame.InitToBlack(320, 240, 1);
- source()->SinkInterfaceForTest()->OnFrame(webrtc_frame);
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+
+ buffer->SetToBlack();
+
+ source()->SinkInterfaceForTest()->OnFrame(
+ cricket::WebRtcVideoFrame(buffer, 1, webrtc::kVideoRotation_0));
run_loop.Run();
EXPECT_EQ(1, sink.number_of_frames());
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index 76888542d54..ea6e87ba9ad 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -20,6 +20,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/common/media/media_stream_messages.h"
#include "content/public/common/content_client.h"
@@ -29,13 +30,12 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/webrtc_ip_handling_policy.h"
#include "content/public/renderer/content_renderer_client.h"
+#include "content/renderer/media/gpu/rtc_video_decoder_factory.h"
+#include "content/renderer/media/gpu/rtc_video_encoder_factory.h"
#include "content/renderer/media/media_stream.h"
#include "content/renderer/media/media_stream_video_source.h"
#include "content/renderer/media/media_stream_video_track.h"
-#include "content/renderer/media/peer_connection_identity_store.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
-#include "content/renderer/media/rtc_video_decoder_factory.h"
-#include "content/renderer/media/rtc_video_encoder_factory.h"
#include "content/renderer/media/webrtc/stun_field_trial.h"
#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
@@ -61,7 +61,6 @@
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/webrtc/api/dtlsidentitystore.h"
#include "third_party/webrtc/api/mediaconstraintsinterface.h"
#include "third_party/webrtc/base/ssladapter.h"
#include "third_party/webrtc/modules/video_coding/codecs/h264/include/h264.h"
@@ -186,13 +185,17 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
CHECK(chrome_signaling_thread_.Start());
CHECK(chrome_worker_thread_.Start());
- base::WaitableEvent start_worker_event(true, false);
+ base::WaitableEvent start_worker_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
chrome_worker_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&PeerConnectionDependencyFactory::InitializeWorkerThread,
base::Unretained(this), &worker_thread_, &start_worker_event));
- base::WaitableEvent create_network_manager_event(true, false);
+ base::WaitableEvent create_network_manager_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
chrome_worker_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&PeerConnectionDependencyFactory::
@@ -211,7 +214,9 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
return;
}
- base::WaitableEvent start_signaling_event(true, false);
+ base::WaitableEvent start_signaling_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
chrome_signaling_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&PeerConnectionDependencyFactory::InitializeSignalingThread,
@@ -290,12 +295,6 @@ PeerConnectionDependencyFactory::CreatePeerConnection(
if (!GetPcFactory().get())
return NULL;
- std::unique_ptr<PeerConnectionIdentityStore> identity_store(
- new PeerConnectionIdentityStore(
- base::ThreadTaskRunnerHandle::Get(), GetWebRtcSignalingThread(),
- GURL(web_frame->document().url()),
- GURL(web_frame->document().firstPartyForCookies())));
-
// Copy the flag from Preference associated with this WebFrame.
P2PPortAllocator::Config port_config;
@@ -387,36 +386,20 @@ PeerConnectionDependencyFactory::CreatePeerConnection(
FilteringNetworkManager* filtering_network_manager =
new FilteringNetworkManager(network_manager_, requesting_origin,
media_permission);
- if (media_permission) {
- // Start permission check earlier to reduce any impact to call set up
- // time. It's safe to use Unretained here since both destructor and
- // Initialize can only be called on the worker thread.
- chrome_worker_thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&FilteringNetworkManager::Initialize,
- base::Unretained(filtering_network_manager)));
- }
network_manager.reset(filtering_network_manager);
} else {
network_manager.reset(new EmptyNetworkManager(network_manager_));
}
std::unique_ptr<P2PPortAllocator> port_allocator(new P2PPortAllocator(
p2p_socket_dispatcher_, std::move(network_manager), socket_factory_.get(),
- port_config, requesting_origin, chrome_worker_thread_.task_runner()));
+ port_config, requesting_origin));
return GetPcFactory()
->CreatePeerConnection(config, std::move(port_allocator),
- std::move(identity_store), observer)
+ nullptr, observer)
.get();
}
-// static
-rtc::scoped_refptr<rtc::RTCCertificate>
-PeerConnectionDependencyFactory::GenerateDefaultCertificate() {
- std::unique_ptr<rtc::SSLIdentity> identity(rtc::SSLIdentity::Generate(
- webrtc::kIdentityName, rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)));
- return rtc::RTCCertificate::Create(std::move(identity));
-}
-
scoped_refptr<webrtc::MediaStreamInterface>
PeerConnectionDependencyFactory::CreateLocalMediaStream(
const std::string& label) {
@@ -496,7 +479,7 @@ void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() {
// The underneath IPC channel has to be connected before sending any IPC
// message.
if (!p2p_socket_dispatcher_->connected()) {
- base::MessageLoop::current()->PostDelayedTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&PeerConnectionDependencyFactory::TryScheduleStunProbeTrial,
base::Unretained(this)),
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index e5e017c5a7c..fc69d224759 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -67,9 +67,6 @@ class CONTENT_EXPORT PeerConnectionDependencyFactory
blink::WebRTCPeerConnectionHandler* CreateRTCPeerConnectionHandler(
blink::WebRTCPeerConnectionHandlerClient* client);
- // Generate an ECDSA certificate.
- static rtc::scoped_refptr<rtc::RTCCertificate> GenerateDefaultCertificate();
-
// Asks the PeerConnection factory to create a Local MediaStream object.
virtual scoped_refptr<webrtc::MediaStreamInterface>
CreateLocalMediaStream(const std::string& label);
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
index 213b2b0d650..2d789a9acc6 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
@@ -11,7 +11,7 @@
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
namespace content {
@@ -109,7 +109,7 @@ WebRtcAudioSink::Adapter::Adapter(
: webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
source_(std::move(source)),
signaling_task_runner_(std::move(signaling_task_runner)),
- main_task_runner_(base::MessageLoop::current()->task_runner()) {
+ main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
DCHECK(signaling_task_runner_);
}
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
index ce302fa88dc..3c437c69431 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -21,7 +21,6 @@
#include "media/base/audio_parameters.h"
#include "media/base/audio_push_fifo.h"
#include "third_party/webrtc/api/mediastreamtrack.h"
-#include "third_party/webrtc/media/base/audiorenderer.h"
namespace content {
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
index 35843d0515c..17641916639 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.cc
@@ -7,21 +7,6 @@
#include "base/logging.h"
namespace content {
-namespace {
-int WebRtcToMediaPlaneType(webrtc::PlaneType type) {
- switch (type) {
- case webrtc::kYPlane:
- return media::VideoFrame::kYPlane;
- case webrtc::kUPlane:
- return media::VideoFrame::kUPlane;
- case webrtc::kVPlane:
- return media::VideoFrame::kVPlane;
- default:
- NOTREACHED();
- return media::VideoFrame::kMaxPlanes;
- }
-}
-} // anonymous namespace
WebRtcVideoFrameAdapter::WebRtcVideoFrameAdapter(
const scoped_refptr<media::VideoFrame>& frame)
@@ -39,12 +24,24 @@ int WebRtcVideoFrameAdapter::height() const {
return frame_->visible_rect().height();
}
-const uint8_t* WebRtcVideoFrameAdapter::data(webrtc::PlaneType type) const {
- return frame_->visible_data(WebRtcToMediaPlaneType(type));
+const uint8_t* WebRtcVideoFrameAdapter::DataY() const {
+ return frame_->visible_data(media::VideoFrame::kYPlane);
+}
+const uint8_t* WebRtcVideoFrameAdapter::DataU() const {
+ return frame_->visible_data(media::VideoFrame::kUPlane);
+}
+const uint8_t* WebRtcVideoFrameAdapter::DataV() const {
+ return frame_->visible_data(media::VideoFrame::kVPlane);
}
-int WebRtcVideoFrameAdapter::stride(webrtc::PlaneType type) const {
- return frame_->stride(WebRtcToMediaPlaneType(type));
+int WebRtcVideoFrameAdapter::StrideY() const {
+ return frame_->stride(media::VideoFrame::kYPlane);
+}
+int WebRtcVideoFrameAdapter::StrideU() const {
+ return frame_->stride(media::VideoFrame::kUPlane);
+}
+int WebRtcVideoFrameAdapter::StrideV() const {
+ return frame_->stride(media::VideoFrame::kVPlane);
}
void* WebRtcVideoFrameAdapter::native_handle() const {
diff --git a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.h
index 61555d032ec..46dd87683d0 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_frame_adapter.h
@@ -24,9 +24,13 @@ class WebRtcVideoFrameAdapter : public webrtc::VideoFrameBuffer {
int width() const override;
int height() const override;
- const uint8_t* data(webrtc::PlaneType type) const override;
+ const uint8_t* DataY() const override;
+ const uint8_t* DataU() const override;
+ const uint8_t* DataV() const override;
- int stride(webrtc::PlaneType type) const override;
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
void* native_handle() const override;
diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.cc b/chromium/content/renderer/media/webrtc_audio_device_impl.cc
index 7f46506fada..2cb2eacbb32 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/chromium/content/renderer/media/webrtc_audio_device_impl.cc
@@ -4,6 +4,7 @@
#include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/win/windows_version.h"
@@ -62,9 +63,15 @@ void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
int sample_rate,
int audio_delay_milliseconds,
base::TimeDelta* current_time) {
- DCHECK(audio_renderer_thread_checker_.CalledOnValidThread());
{
base::AutoLock auto_lock(lock_);
+#if DCHECK_IS_ON()
+ DCHECK(renderer_->CurrentThreadIsRenderingThread());
+ if (!audio_renderer_thread_checker_.CalledOnValidThread()) {
+ for (const auto& sink : playout_sinks_)
+ sink->OnRenderThreadChanged();
+ }
+#endif
if (!playing_) {
// Force silence to AudioBus after stopping playout in case
// there is lingering audio data in AudioBus.
diff --git a/chromium/content/renderer/media/webrtc_audio_device_impl.h b/chromium/content/renderer/media/webrtc_audio_device_impl.h
index 6af4a869356..1e3f05f1a64 100644
--- a/chromium/content/renderer/media/webrtc_audio_device_impl.h
+++ b/chromium/content/renderer/media/webrtc_audio_device_impl.h
@@ -219,7 +219,7 @@ class WebRtcPlayoutDataSource {
class Sink {
public:
// Callback to get the playout data.
- // Called on the render audio thread.
+ // Called on the audio render thread.
virtual void OnPlayoutData(media::AudioBus* audio_bus,
int sample_rate,
int audio_delay_milliseconds) = 0;
@@ -228,6 +228,11 @@ class WebRtcPlayoutDataSource {
// Called on the main render thread.
virtual void OnPlayoutDataSourceChanged() = 0;
+ // Called to notify that the audio render thread has changed, and
+ // OnPlayoutData() will from now on be called on the new thread.
+ // Called on the new audio render thread.
+ virtual void OnRenderThreadChanged() = 0;
+
protected:
virtual ~Sink() {}
};
diff --git a/chromium/content/renderer/media/webrtc_audio_renderer.cc b/chromium/content/renderer/media/webrtc_audio_renderer.cc
index 604ed959a0d..da693872812 100644
--- a/chromium/content/renderer/media/webrtc_audio_renderer.cc
+++ b/chromium/content/renderer/media/webrtc_audio_renderer.cc
@@ -20,10 +20,10 @@
#include "content/renderer/media/webrtc_logging.h"
#include "media/audio/sample_rates.h"
#include "media/base/audio_capturer_source.h"
+#include "media/base/audio_latency.h"
#include "media/base/audio_parameters.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
-#include "third_party/webrtc/media/base/audiorenderer.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -153,39 +153,6 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
} // namespace
-int WebRtcAudioRenderer::GetOptimalBufferSize(int sample_rate,
- int hardware_buffer_size) {
- // Use native hardware buffer size as default. On Windows, we strive to open
- // up using this native hardware buffer size to achieve best
- // possible performance and to ensure that no FIFO is needed on the browser
- // side to match the client request. That is why there is no #if case for
- // Windows below.
- int frames_per_buffer = hardware_buffer_size;
-
-#if defined(OS_LINUX) || defined(OS_MACOSX)
- // On Linux and MacOS, the low level IO implementations on the browser side
- // supports all buffer size the clients want. We use the native peer
- // connection buffer size (10ms) to achieve best possible performance.
- frames_per_buffer = sample_rate / 100;
-#elif defined(OS_ANDROID)
- // TODO(henrika): Keep tuning this scheme and espcicially for low-latency
- // cases. Might not be possible to come up with the perfect solution using
- // the render side only.
- int frames_per_10ms = sample_rate / 100;
- if (frames_per_buffer < 2 * frames_per_10ms) {
- // Examples of low-latency frame sizes and the resulting |buffer_size|:
- // Nexus 7 : 240 audio frames => 2*480 = 960
- // Nexus 10 : 256 => 2*441 = 882
- // Galaxy Nexus: 144 => 2*441 = 882
- frames_per_buffer = 2 * frames_per_10ms;
- DVLOG(1) << "Low-latency output detected on Android";
- }
-#endif
-
- DVLOG(1) << "Using sink output buffer size: " << frames_per_buffer;
- return frames_per_buffer;
-}
-
WebRtcAudioRenderer::WebRtcAudioRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread,
const blink::WebMediaStream& media_stream,
@@ -209,7 +176,6 @@ WebRtcAudioRenderer::WebRtcAudioRenderer(
WebRtcLogMessage(base::StringPrintf(
"WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i",
source_render_frame_id, session_id, sink_params_.effects()));
- audio_renderer_thread_checker_.DetachFromThread();
}
WebRtcAudioRenderer::~WebRtcAudioRenderer() {
@@ -241,7 +207,7 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
PrepareSink();
{
// No need to reassert the preconditions because the other thread accessing
- // the fields (checked by |audio_renderer_thread_checker_|) only reads them.
+ // the fields only reads them.
base::AutoLock auto_lock(lock_);
source_ = source;
@@ -267,6 +233,10 @@ bool WebRtcAudioRenderer::IsStarted() const {
return start_ref_count_ != 0;
}
+bool WebRtcAudioRenderer::CurrentThreadIsRenderingThread() {
+ return sink_->CurrentThreadIsRenderingThread();
+}
+
void WebRtcAudioRenderer::Start() {
DVLOG(1) << "WebRtcAudioRenderer::Start()";
DCHECK(thread_checker_.CalledOnValidThread());
@@ -407,7 +377,6 @@ void WebRtcAudioRenderer::SwitchOutputDevice(
// callback may currently be executing and trying to grab the lock while we're
// stopping the thread on which it runs.
sink_->Stop();
- audio_renderer_thread_checker_.DetachFromThread();
sink_ = new_sink;
output_device_id_ = device_id;
security_origin_ = security_origin;
@@ -424,7 +393,7 @@ void WebRtcAudioRenderer::SwitchOutputDevice(
int WebRtcAudioRenderer::Render(media::AudioBus* audio_bus,
uint32_t frames_delayed,
uint32_t frames_skipped) {
- DCHECK(audio_renderer_thread_checker_.CalledOnValidThread());
+ DCHECK(sink_->CurrentThreadIsRenderingThread());
base::AutoLock auto_lock(lock_);
if (!source_)
return 0;
@@ -481,7 +450,7 @@ void WebRtcAudioRenderer::OnRenderError() {
// Called by AudioPullFifo when more data is necessary.
void WebRtcAudioRenderer::SourceCallback(
int fifo_frame_delay, media::AudioBus* audio_bus) {
- DCHECK(audio_renderer_thread_checker_.CalledOnValidThread());
+ DCHECK(sink_->CurrentThreadIsRenderingThread());
base::TimeTicks start_time = base::TimeTicks::Now();
DVLOG(2) << "WebRtcAudioRenderer::SourceCallback("
<< fifo_frame_delay << ", "
@@ -654,7 +623,7 @@ void WebRtcAudioRenderer::PrepareSink() {
DVLOG(1) << "Using WebRTC output buffer size: " << source_frames_per_buffer;
// Setup sink parameters.
- const int sink_frames_per_buffer = GetOptimalBufferSize(
+ const int sink_frames_per_buffer = media::AudioLatency::GetRtcBufferSize(
sample_rate, device_info.output_params().frames_per_buffer());
new_sink_params.set_sample_rate(sample_rate);
new_sink_params.set_frames_per_buffer(sink_frames_per_buffer);
diff --git a/chromium/content/renderer/media/webrtc_audio_renderer.h b/chromium/content/renderer/media/webrtc_audio_renderer.h
index f13ac8d5bef..f4f677ee58f 100644
--- a/chromium/content/renderer/media/webrtc_audio_renderer.h
+++ b/chromium/content/renderer/media/webrtc_audio_renderer.h
@@ -73,10 +73,6 @@ class CONTENT_EXPORT WebRtcAudioRenderer
float volume_;
};
-
- // Returns platform specific optimal buffer size for rendering audio.
- static int GetOptimalBufferSize(int sample_rate, int hardware_buffer_size);
-
WebRtcAudioRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread,
const blink::WebMediaStream& media_stream,
@@ -109,6 +105,9 @@ class CONTENT_EXPORT WebRtcAudioRenderer
int sample_rate() const { return sink_params_.sample_rate(); }
int frames_per_buffer() const { return sink_params_.frames_per_buffer(); }
+ // Returns true if called on rendering thread, otherwise false.
+ bool CurrentThreadIsRenderingThread();
+
private:
// MediaStreamAudioRenderer implementation. This is private since we want
// callers to use proxy objects.
@@ -155,7 +154,6 @@ class CONTENT_EXPORT WebRtcAudioRenderer
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
- base::ThreadChecker audio_renderer_thread_checker_;
// Flag to keep track the state of the renderer.
State state_;
diff --git a/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc b/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
index d77df9ac552..af465017c68 100644
--- a/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
+++ b/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
@@ -130,8 +130,8 @@ void WebRtcLocalAudioSourceProvider::provideInput(
audio_converter_->Convert(output_wrapper_.get());
}
-double WebRtcLocalAudioSourceProvider::ProvideInput(
- media::AudioBus* audio_bus, base::TimeDelta buffer_delay) {
+double WebRtcLocalAudioSourceProvider::ProvideInput(media::AudioBus* audio_bus,
+ uint32_t frames_delayed) {
if (fifo_->frames() >= audio_bus->frames()) {
fifo_->Consume(audio_bus, 0, audio_bus->frames());
} else {
diff --git a/chromium/content/renderer/media/webrtc_local_audio_source_provider.h b/chromium/content/renderer/media/webrtc_local_audio_source_provider.h
index f5a867fc949..cbf8d7980ad 100644
--- a/chromium/content/renderer/media/webrtc_local_audio_source_provider.h
+++ b/chromium/content/renderer/media/webrtc_local_audio_source_provider.h
@@ -75,7 +75,7 @@ class CONTENT_EXPORT WebRtcLocalAudioSourceProvider
// This function is triggered by provideInput()on the WebAudio audio thread,
// so it has been under the protection of |lock_|.
double ProvideInput(media::AudioBus* audio_bus,
- base::TimeDelta buffer_delay) override;
+ uint32_t frames_delayed) override;
// Method to allow the unittests to inject its own sink parameters to avoid
// query the hardware.
diff --git a/chromium/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc b/chromium/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc
index 6eda8f178ec..b4013097e2d 100644
--- a/chromium/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc
+++ b/chromium/content/renderer/media/webrtc_local_audio_source_provider_unittest.cc
@@ -33,7 +33,7 @@ class WebRtcLocalAudioSourceProviderTest : public testing::Test {
false /* remote */);
blink_track_.initialize(blink::WebString::fromUTF8("audio_track"),
audio_source);
- blink_track_.setExtraData(new MediaStreamAudioTrack(true));
+ blink_track_.setTrackData(new MediaStreamAudioTrack(true));
source_provider_.reset(new WebRtcLocalAudioSourceProvider(blink_track_));
source_provider_->SetSinkParamsForTesting(sink_params_);
source_provider_->OnSetFormat(source_params_);
diff --git a/chromium/content/renderer/mojo/blink_service_registry_impl.cc b/chromium/content/renderer/mojo/blink_service_registry_impl.cc
index 6a2fdf09a6a..408f6de8064 100644
--- a/chromium/content/renderer/mojo/blink_service_registry_impl.cc
+++ b/chromium/content/renderer/mojo/blink_service_registry_impl.cc
@@ -6,23 +6,36 @@
#include <utility>
-#include "content/common/mojo/service_registry_impl.h"
+#include "base/bind.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "services/shell/public/cpp/interface_provider.h"
namespace content {
BlinkServiceRegistryImpl::BlinkServiceRegistryImpl(
- base::WeakPtr<content::ServiceRegistry> service_registry)
- : service_registry_(service_registry) {}
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces)
+ : remote_interfaces_(remote_interfaces),
+ main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ weak_ptr_factory_(this) {}
BlinkServiceRegistryImpl::~BlinkServiceRegistryImpl() = default;
void BlinkServiceRegistryImpl::connectToRemoteService(
const char* name,
mojo::ScopedMessagePipeHandle handle) {
- if (!service_registry_)
+ if (!main_thread_task_runner_->BelongsToCurrentThread()) {
+ main_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&BlinkServiceRegistryImpl::connectToRemoteService,
+ weak_ptr_factory_.GetWeakPtr(), name,
+ base::Passed(&handle)));
return;
+ }
- service_registry_->ConnectToRemoteService(name, std::move(handle));
+ if (!remote_interfaces_)
+ return;
+
+ remote_interfaces_->GetInterface(name, std::move(handle));
}
} // namespace content
diff --git a/chromium/content/renderer/mojo/blink_service_registry_impl.h b/chromium/content/renderer/mojo/blink_service_registry_impl.h
index 8bd86321e68..2fc08ae35f3 100644
--- a/chromium/content/renderer/mojo/blink_service_registry_impl.h
+++ b/chromium/content/renderer/mojo/blink_service_registry_impl.h
@@ -6,20 +6,27 @@
#define CONTENT_RENDERER_MOJO_BLINK_SERVICE_REGISTRY_IMPL_H_
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "third_party/WebKit/public/platform/ServiceRegistry.h"
-namespace content {
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace shell {
+class InterfaceProvider;
+}
-class ServiceRegistry;
+namespace content {
// An implementation of blink::ServiceRegistry that forwards to a
-// content::ServiceRegistry.
+// shell::InterfaceProvider.
class BlinkServiceRegistryImpl : public blink::ServiceRegistry {
public:
explicit BlinkServiceRegistryImpl(
- base::WeakPtr<content::ServiceRegistry> service_registry);
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces);
~BlinkServiceRegistryImpl();
// blink::ServiceRegistry override.
@@ -27,7 +34,11 @@ class BlinkServiceRegistryImpl : public blink::ServiceRegistry {
mojo::ScopedMessagePipeHandle handle) override;
private:
- const base::WeakPtr<content::ServiceRegistry> service_registry_;
+ const base::WeakPtr<shell::InterfaceProvider> remote_interfaces_;
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
+ base::WeakPtrFactory<BlinkServiceRegistryImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BlinkServiceRegistryImpl);
};
diff --git a/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc b/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc
new file mode 100644
index 00000000000..174455d525a
--- /dev/null
+++ b/chromium/content/renderer/mojo/interface_provider_js_wrapper.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/mojo/interface_provider_js_wrapper.h"
+
+#include <memory>
+#include <utility>
+
+#include "mojo/edk/js/handle.h"
+#include "services/shell/public/cpp/interface_provider.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+
+namespace content {
+
+gin::WrapperInfo InterfaceProviderJsWrapper::kWrapperInfo = {
+ gin::kEmbedderNativeGin};
+const char InterfaceProviderJsWrapper::kPerFrameModuleName[] =
+ "content/public/renderer/frame_service_registry";
+const char InterfaceProviderJsWrapper::kPerProcessModuleName[] =
+ "content/public/renderer/service_registry";
+
+InterfaceProviderJsWrapper::~InterfaceProviderJsWrapper() {
+}
+
+// static
+gin::Handle<InterfaceProviderJsWrapper>
+InterfaceProviderJsWrapper::Create(
+ v8::Isolate* isolate,
+ v8::Handle<v8::Context> context,
+ shell::InterfaceProvider* remote_interfaces) {
+ return gin::CreateHandle(
+ isolate,
+ new InterfaceProviderJsWrapper(
+ isolate, context,
+ remote_interfaces->GetWeakPtr()));
+}
+
+gin::ObjectTemplateBuilder
+InterfaceProviderJsWrapper::GetObjectTemplateBuilder(v8::Isolate* isolate) {
+ return Wrappable<InterfaceProviderJsWrapper>::GetObjectTemplateBuilder(
+ isolate)
+ .SetMethod("connectToService",
+ &InterfaceProviderJsWrapper::GetInterface)
+ .SetMethod("addServiceOverrideForTesting",
+ &InterfaceProviderJsWrapper::AddOverrideForTesting)
+ .SetMethod("clearServiceOverridesForTesting",
+ &InterfaceProviderJsWrapper::ClearOverridesForTesting);
+}
+
+mojo::Handle InterfaceProviderJsWrapper::GetInterface(
+ const std::string& interface_name) {
+ mojo::MessagePipe pipe;
+ if (remote_interfaces_) {
+ remote_interfaces_->GetInterface(
+ interface_name, std::move(pipe.handle0));
+ }
+ return pipe.handle1.release();
+}
+
+void InterfaceProviderJsWrapper::AddOverrideForTesting(
+ const std::string& interface_name,
+ v8::Local<v8::Function> service_factory) {
+ ScopedJsFactory factory(v8::Isolate::GetCurrent(), service_factory);
+ shell::InterfaceProvider::TestApi test_api(remote_interfaces_.get());
+ test_api.SetBinderForName(
+ interface_name,
+ base::Bind(&InterfaceProviderJsWrapper::CallJsFactory,
+ weak_factory_.GetWeakPtr(), factory));
+}
+
+void InterfaceProviderJsWrapper::ClearOverridesForTesting() {
+ shell::InterfaceProvider::TestApi test_api(remote_interfaces_.get());
+ test_api.ClearBinders();
+}
+
+InterfaceProviderJsWrapper::InterfaceProviderJsWrapper(
+ v8::Isolate* isolate,
+ v8::Handle<v8::Context> context,
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces)
+ : isolate_(isolate),
+ context_(isolate, context),
+ remote_interfaces_(remote_interfaces),
+ weak_factory_(this) {
+ context_.SetWeak(this, &InterfaceProviderJsWrapper::ClearContext,
+ v8::WeakCallbackType::kParameter);
+}
+
+void InterfaceProviderJsWrapper::CallJsFactory(
+ const ScopedJsFactory& factory,
+ mojo::ScopedMessagePipeHandle pipe) {
+ if (context_.IsEmpty())
+ return;
+
+ v8::HandleScope handle_scope(isolate_);
+ v8::Handle<v8::Context> context = context_.Get(isolate_);
+ v8::Context::Scope context_scope(context);
+ v8::Local<v8::Value> argv[] = {
+ gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
+ blink::WebLocalFrame::frameForContext(context)
+ ->callFunctionEvenIfScriptDisabled(factory.Get(isolate_),
+ v8::Undefined(isolate_), 1, argv);
+}
+
+// static
+void InterfaceProviderJsWrapper::ClearContext(
+ const v8::WeakCallbackInfo<InterfaceProviderJsWrapper>& data) {
+ InterfaceProviderJsWrapper* registry = data.GetParameter();
+ registry->context_.Reset();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/mojo/interface_provider_js_wrapper.h b/chromium/content/renderer/mojo/interface_provider_js_wrapper.h
new file mode 100644
index 00000000000..0c5c6eb9bac
--- /dev/null
+++ b/chromium/content/renderer/mojo/interface_provider_js_wrapper.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MOJO_INTERFACE_PROVIDER_JS_WRAPPER_H_
+#define CONTENT_RENDERER_MOJO_INTERFACE_PROVIDER_JS_WRAPPER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "gin/handle.h"
+#include "gin/object_template_builder.h"
+#include "gin/wrappable.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "v8/include/v8.h"
+
+namespace shell {
+class InterfaceProvider;
+}
+
+namespace content {
+
+// A JS wrapper around shell::InterfaceProvider that allows connecting to
+// remote services.
+class CONTENT_EXPORT InterfaceProviderJsWrapper
+ : public gin::Wrappable<InterfaceProviderJsWrapper> {
+ public:
+ ~InterfaceProviderJsWrapper() override;
+ static gin::Handle<InterfaceProviderJsWrapper> Create(
+ v8::Isolate* isolate,
+ v8::Handle<v8::Context> context,
+ shell::InterfaceProvider* remote_interfaces);
+
+ // gin::Wrappable<InterfaceProviderJsWrapper> overrides.
+ gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) override;
+
+ // JS interface implementation.
+ void AddOverrideForTesting(const std::string& interface_name,
+ v8::Local<v8::Function> interface_factory);
+ void ClearOverridesForTesting();
+ mojo::Handle GetInterface(const std::string& interface_name);
+
+ static gin::WrapperInfo kWrapperInfo;
+ static const char kPerFrameModuleName[];
+ static const char kPerProcessModuleName[];
+
+ private:
+ using ScopedJsFactory =
+ v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>>;
+
+ InterfaceProviderJsWrapper(
+ v8::Isolate* isolate,
+ v8::Handle<v8::Context> context,
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces);
+
+ void CallJsFactory(const ScopedJsFactory& factory,
+ mojo::ScopedMessagePipeHandle pipe);
+
+ static void ClearContext(
+ const v8::WeakCallbackInfo<InterfaceProviderJsWrapper>& data);
+
+ v8::Isolate* isolate_;
+ v8::Global<v8::Context> context_;
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces_;
+
+ base::WeakPtrFactory<InterfaceProviderJsWrapper> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(InterfaceProviderJsWrapper);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MOJO_INTERFACE_PROVIDER_JS_WRAPPER_H_
diff --git a/chromium/content/renderer/mojo/service_registry_js_wrapper.cc b/chromium/content/renderer/mojo/service_registry_js_wrapper.cc
deleted file mode 100644
index 8b5793820e3..00000000000
--- a/chromium/content/renderer/mojo/service_registry_js_wrapper.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/mojo/service_registry_js_wrapper.h"
-
-#include <memory>
-#include <utility>
-
-#include "content/common/mojo/service_registry_impl.h"
-#include "content/public/common/service_registry.h"
-#include "mojo/edk/js/handle.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-
-namespace content {
-
-gin::WrapperInfo ServiceRegistryJsWrapper::kWrapperInfo = {
- gin::kEmbedderNativeGin};
-const char ServiceRegistryJsWrapper::kPerFrameModuleName[] =
- "content/public/renderer/frame_service_registry";
-const char ServiceRegistryJsWrapper::kPerProcessModuleName[] =
- "content/public/renderer/service_registry";
-
-ServiceRegistryJsWrapper::~ServiceRegistryJsWrapper() {
-}
-
-// static
-gin::Handle<ServiceRegistryJsWrapper> ServiceRegistryJsWrapper::Create(
- v8::Isolate* isolate,
- v8::Handle<v8::Context> context,
- ServiceRegistry* service_registry) {
- return gin::CreateHandle(
- isolate,
- new ServiceRegistryJsWrapper(
- isolate, context,
- static_cast<ServiceRegistryImpl*>(service_registry)->GetWeakPtr()));
-}
-
-gin::ObjectTemplateBuilder ServiceRegistryJsWrapper::GetObjectTemplateBuilder(
- v8::Isolate* isolate) {
- return Wrappable<ServiceRegistryJsWrapper>::GetObjectTemplateBuilder(isolate)
- .SetMethod("connectToService",
- &ServiceRegistryJsWrapper::ConnectToService)
- .SetMethod("addServiceOverrideForTesting",
- &ServiceRegistryJsWrapper::AddServiceOverrideForTesting)
- .SetMethod("clearServiceOverridesForTesting",
- &ServiceRegistryJsWrapper::ClearServiceOverridesForTesting);
-}
-
-mojo::Handle ServiceRegistryJsWrapper::ConnectToService(
- const std::string& service_name) {
- mojo::MessagePipe pipe;
- if (service_registry_)
- service_registry_->ConnectToRemoteService(service_name,
- std::move(pipe.handle0));
- return pipe.handle1.release();
-}
-
-void ServiceRegistryJsWrapper::AddServiceOverrideForTesting(
- const std::string& service_name,
- v8::Local<v8::Function> service_factory) {
- ServiceRegistry* registry = service_registry_.get();
- if (!registry)
- return;
- ScopedJsFactory factory(v8::Isolate::GetCurrent(), service_factory);
- registry->AddServiceOverrideForTesting(
- service_name, base::Bind(&ServiceRegistryJsWrapper::CallJsFactory,
- weak_factory_.GetWeakPtr(), factory));
-}
-
-void ServiceRegistryJsWrapper::ClearServiceOverridesForTesting() {
- ServiceRegistryImpl* registry =
- static_cast<ServiceRegistryImpl*>(service_registry_.get());
- if (!registry)
- return;
-
- registry->ClearServiceOverridesForTesting();
-}
-
-ServiceRegistryJsWrapper::ServiceRegistryJsWrapper(
- v8::Isolate* isolate,
- v8::Handle<v8::Context> context,
- base::WeakPtr<ServiceRegistry> service_registry)
- : isolate_(isolate),
- context_(isolate, context),
- service_registry_(service_registry),
- weak_factory_(this) {
- context_.SetWeak(this, &ServiceRegistryJsWrapper::ClearContext,
- v8::WeakCallbackType::kParameter);
-}
-
-void ServiceRegistryJsWrapper::CallJsFactory(
- const ScopedJsFactory& factory,
- mojo::ScopedMessagePipeHandle pipe) {
- if (context_.IsEmpty())
- return;
-
- v8::HandleScope handle_scope(isolate_);
- v8::Handle<v8::Context> context = context_.Get(isolate_);
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Value> argv[] = {
- gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
- blink::WebLocalFrame::frameForContext(context)
- ->callFunctionEvenIfScriptDisabled(factory.Get(isolate_),
- v8::Undefined(isolate_), 1, argv);
-}
-
-// static
-void ServiceRegistryJsWrapper::ClearContext(
- const v8::WeakCallbackInfo<ServiceRegistryJsWrapper>& data) {
- ServiceRegistryJsWrapper* service_registry = data.GetParameter();
- service_registry->context_.Reset();
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/mojo/service_registry_js_wrapper.h b/chromium/content/renderer/mojo/service_registry_js_wrapper.h
deleted file mode 100644
index 5fc2f63729b..00000000000
--- a/chromium/content/renderer/mojo/service_registry_js_wrapper.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MOJO_SERVICE_REGISTRY_JS_WRAPPER_H_
-#define CONTENT_RENDERER_MOJO_SERVICE_REGISTRY_JS_WRAPPER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "gin/handle.h"
-#include "gin/object_template_builder.h"
-#include "gin/wrappable.h"
-#include "mojo/public/cpp/system/message_pipe.h"
-#include "v8/include/v8.h"
-
-namespace content {
-
-class ServiceRegistry;
-
-// A JS wrapper around ServiceRegistry that allows connecting to remote
-// services.
-class CONTENT_EXPORT ServiceRegistryJsWrapper
- : public gin::Wrappable<ServiceRegistryJsWrapper> {
- public:
- ~ServiceRegistryJsWrapper() override;
- static gin::Handle<ServiceRegistryJsWrapper> Create(
- v8::Isolate* isolate,
- v8::Handle<v8::Context> context,
- ServiceRegistry* service_registry);
-
- // gin::Wrappable<ServiceRegistryJsWrapper> overrides.
- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
-
- // JS interface implementation.
- void AddServiceOverrideForTesting(const std::string& service_name,
- v8::Local<v8::Function> service_factory);
- void ClearServiceOverridesForTesting();
- mojo::Handle ConnectToService(const std::string& service_name);
-
- static gin::WrapperInfo kWrapperInfo;
- static const char kPerFrameModuleName[];
- static const char kPerProcessModuleName[];
-
- private:
- using ScopedJsFactory =
- v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>>;
-
- ServiceRegistryJsWrapper(v8::Isolate* isolate,
- v8::Handle<v8::Context> context,
- base::WeakPtr<ServiceRegistry> service_registry);
-
- void CallJsFactory(const ScopedJsFactory& factory,
- mojo::ScopedMessagePipeHandle pipe);
-
- static void ClearContext(
- const v8::WeakCallbackInfo<ServiceRegistryJsWrapper>& data);
-
- v8::Isolate* isolate_;
- v8::Global<v8::Context> context_;
- base::WeakPtr<ServiceRegistry> service_registry_;
-
- base::WeakPtrFactory<ServiceRegistryJsWrapper> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceRegistryJsWrapper);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MOJO_SERVICE_REGISTRY_JS_WRAPPER_H_
diff --git a/chromium/content/renderer/mojo_bindings_controller.cc b/chromium/content/renderer/mojo_bindings_controller.cc
index 135c5adf0ef..56cf602c0c3 100644
--- a/chromium/content/renderer/mojo_bindings_controller.cc
+++ b/chromium/content/renderer/mojo_bindings_controller.cc
@@ -98,4 +98,8 @@ void MojoBindingsController::DidClearWindowObject() {
DestroyContextState(render_frame()->GetWebFrame()->mainWorldScriptContext());
}
+void MojoBindingsController::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/mojo_bindings_controller.h b/chromium/content/renderer/mojo_bindings_controller.h
index d26f17a85cf..b0a3fb6f8e8 100644
--- a/chromium/content/renderer/mojo_bindings_controller.h
+++ b/chromium/content/renderer/mojo_bindings_controller.h
@@ -43,6 +43,7 @@ class MojoBindingsController
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void DidClearWindowObject() override;
+ void OnDestruct() override;
const bool for_layout_tests_;
diff --git a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
index 2a0fd6b4778..685da6d7b57 100644
--- a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
+++ b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
@@ -30,7 +30,7 @@ class MouseLockDispatcherTest : public RenderViewTest {
public:
void SetUp() override {
RenderViewTest::SetUp();
- route_id_ = view()->GetRoutingID();
+ route_id_ = view()->GetWidget()->routing_id();
target_ = new MockLockTarget();
alternate_target_ = new MockLockTarget();
}
@@ -43,6 +43,7 @@ class MouseLockDispatcherTest : public RenderViewTest {
protected:
RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
+ RenderWidget* widget() { return view()->GetWidget(); }
MouseLockDispatcher* dispatcher() { return view()->mouse_lock_dispatcher(); }
int route_id_;
MockLockTarget* target_;
@@ -54,22 +55,22 @@ class MouseLockDispatcherTest : public RenderViewTest {
// Test simple use of RenderViewImpl interface to WebKit for pointer lock.
TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
// Start unlocked.
- EXPECT_FALSE(view()->isPointerLocked());
+ EXPECT_FALSE(widget()->isPointerLocked());
// Lock.
- EXPECT_TRUE(view()->requestPointerLock());
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
- EXPECT_TRUE(view()->isPointerLocked());
+ EXPECT_TRUE(widget()->requestPointerLock());
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ EXPECT_TRUE(widget()->isPointerLocked());
// Unlock.
- view()->requestPointerUnlock();
- view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
- EXPECT_FALSE(view()->isPointerLocked());
+ widget()->requestPointerUnlock();
+ widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ EXPECT_FALSE(widget()->isPointerLocked());
// Attempt a lock, and have it fail.
- EXPECT_TRUE(view()->requestPointerLock());
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
- EXPECT_FALSE(view()->isPointerLocked());
+ EXPECT_TRUE(widget()->requestPointerLock());
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ EXPECT_FALSE(widget()->isPointerLocked());
}
// Test simple use of MouseLockDispatcher with a mock LockTarget.
@@ -86,7 +87,7 @@ TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Receive mouse event.
@@ -94,12 +95,12 @@ TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
// Unlock.
dispatcher()->UnlockMouse(target_);
- view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
// Attempt a lock, and have it fail.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
@@ -112,7 +113,7 @@ TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Unlock, with a deleted target.
@@ -121,7 +122,7 @@ TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
delete target_;
target_ = NULL;
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
- view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
@@ -140,7 +141,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
target_ = NULL;
// Lock response.
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
}
// Test deleting a target that is pending a lock request failure response.
@@ -158,7 +159,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
target_ = NULL;
// Lock response.
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
}
// Test not receiving mouse events when a target is not locked.
@@ -175,7 +176,7 @@ TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Receive mouse event.
@@ -183,7 +184,7 @@ TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
// Unlock.
dispatcher()->UnlockMouse(target_);
- view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
// (Don't) receive mouse event.
@@ -208,7 +209,7 @@ TEST_F(MouseLockDispatcherTest, MultipleTargets) {
EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
// Lock completion for target.
- view()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Fail attempt to lock alternate.
@@ -226,7 +227,7 @@ TEST_F(MouseLockDispatcherTest, MultipleTargets) {
// Though the call to UnlockMouse should not unlock any target, we will
// cause an unlock (as if e.g. user escaped mouse lock) and verify the
// correct target is unlocked.
- view()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
diff --git a/chromium/content/renderer/mus/BUILD.gn b/chromium/content/renderer/mus/BUILD.gn
index c2d3f93d317..12500af1f8b 100644
--- a/chromium/content/renderer/mus/BUILD.gn
+++ b/chromium/content/renderer/mus/BUILD.gn
@@ -26,12 +26,10 @@ source_set("mus") {
"//content/public/common:common_sources",
"//mojo/common",
"//mojo/converters/blink",
- "//mojo/converters/geometry",
- "//mojo/converters/input_events",
- "//mojo/converters/surfaces",
"//services/shell/public/cpp",
"//third_party/WebKit/public:blink",
"//ui/events:events",
"//ui/events:events_base",
+ "//ui/gfx/geometry/mojo",
]
}
diff --git a/chromium/content/renderer/mus/compositor_mus_connection.cc b/chromium/content/renderer/mus/compositor_mus_connection.cc
index fe2445fc600..322fa11becb 100644
--- a/chromium/content/renderer/mus/compositor_mus_connection.cc
+++ b/chromium/content/renderer/mus/compositor_mus_connection.cc
@@ -9,8 +9,8 @@
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/mus/render_widget_mus_connection.h"
#include "mojo/converters/blink/blink_input_events_type_converters.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
#include "ui/events/latency_info.h"
+#include "ui/events/mojo/event.mojom.h"
using mus::mojom::EventResult;
@@ -36,7 +36,7 @@ CompositorMusConnection::CompositorMusConnection(
DCHECK(main_task_runner_->BelongsToCurrentThread());
compositor_task_runner_->PostTask(
FROM_HERE, base::Bind(&CompositorMusConnection::
- CreateWindowTreeConnectionOnCompositorThread,
+ CreateWindowTreeClientOnCompositorThread,
this, base::Passed(std::move(request))));
}
@@ -61,12 +61,10 @@ void CompositorMusConnection::AttachSurfaceOnCompositorThread(
}
}
-void CompositorMusConnection::CreateWindowTreeConnectionOnCompositorThread(
+void CompositorMusConnection::CreateWindowTreeClientOnCompositorThread(
mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) {
DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- mus::WindowTreeConnection::Create(
- this, std::move(request),
- mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED);
+ new mus::WindowTreeClient(this, nullptr, std::move(request));
}
void CompositorMusConnection::OnConnectionLostOnMainThread() {
@@ -98,8 +96,8 @@ void CompositorMusConnection::OnWindowInputEventAckOnMainThread(
compositor_task_runner_->PostTask(FROM_HERE, base::Bind(ack, result));
}
-void CompositorMusConnection::OnConnectionLost(
- mus::WindowTreeConnection* connection) {
+void CompositorMusConnection::OnWindowTreeClientDestroyed(
+ mus::WindowTreeClient* client) {
DCHECK(compositor_task_runner_->BelongsToCurrentThread());
main_task_runner_->PostTask(
FROM_HERE,
diff --git a/chromium/content/renderer/mus/compositor_mus_connection.h b/chromium/content/renderer/mus/compositor_mus_connection.h
index d8a75a67df5..a49b3a7bc2f 100644
--- a/chromium/content/renderer/mus/compositor_mus_connection.h
+++ b/chromium/content/renderer/mus/compositor_mus_connection.h
@@ -10,8 +10,8 @@
#include "base/macros.h"
#include "components/mus/public/cpp/input_event_handler.h"
#include "components/mus/public/cpp/window.h"
-#include "components/mus/public/cpp/window_tree_connection.h"
-#include "components/mus/public/cpp/window_tree_delegate.h"
+#include "components/mus/public/cpp/window_tree_client.h"
+#include "components/mus/public/cpp/window_tree_client_delegate.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -26,7 +26,7 @@ class InputHandlerManager;
// default all other methods are assumed to run on the compositor thread unless
// explicited suffixed with OnMainThread.
class CONTENT_EXPORT CompositorMusConnection
- : NON_EXPORTED_BASE(public mus::WindowTreeDelegate),
+ : NON_EXPORTED_BASE(public mus::WindowTreeClientDelegate),
NON_EXPORTED_BASE(public mus::InputEventHandler),
public base::RefCountedThreadSafe<CompositorMusConnection> {
public:
@@ -52,8 +52,8 @@ class CONTENT_EXPORT CompositorMusConnection
void AttachSurfaceOnCompositorThread(
std::unique_ptr<mus::WindowSurfaceBinding> surface_binding);
- void CreateWindowTreeConnectionOnCompositorThread(
- mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request);
+ void CreateWindowTreeClientOnCompositorThread(
+ mus::mojom::WindowTreeClientRequest request);
void OnConnectionLostOnMainThread();
@@ -65,8 +65,8 @@ class CONTENT_EXPORT CompositorMusConnection
const base::Callback<void(mus::mojom::EventResult)>& ack,
mus::mojom::EventResult result);
- // WindowTreeDelegate implementation:
- void OnConnectionLost(mus::WindowTreeConnection* connection) override;
+ // WindowTreeClientDelegate implementation:
+ void OnWindowTreeClientDestroyed(mus::WindowTreeClient* client) override;
void OnEmbed(mus::Window* root) override;
void OnEventObserved(const ui::Event& event, mus::Window* target) override;
diff --git a/chromium/content/renderer/mus/compositor_mus_connection_unittest.cc b/chromium/content/renderer/mus/compositor_mus_connection_unittest.cc
index 45f621bd771..441674ce4b6 100644
--- a/chromium/content/renderer/mus/compositor_mus_connection_unittest.cc
+++ b/chromium/content/renderer/mus/compositor_mus_connection_unittest.cc
@@ -11,9 +11,6 @@
#include "base/test/test_simple_task_runner.h"
#include "base/time/time.h"
#include "components/mus/public/cpp/tests/test_window.h"
-#include "components/mus/public/interfaces/input_event_constants.mojom.h"
-#include "components/mus/public/interfaces/input_events.mojom.h"
-#include "components/mus/public/interfaces/input_key_codes.mojom.h"
#include "content/common/input/did_overscroll_params.h"
#include "content/common/input/input_event_ack.h"
#include "content/common/input/input_event_ack_state.h"
@@ -28,6 +25,9 @@
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_utils.h"
+#include "ui/events/mojo/event.mojom.h"
+#include "ui/events/mojo/event_constants.mojom.h"
+#include "ui/events/mojo/keyboard_codes.mojom.h"
using mus::mojom::EventResult;
@@ -442,9 +442,10 @@ TEST_F(CompositorMusConnectionTest, InputHandlerConsumes) {
// CompositorMusConnection does not consume the ack, nor calls it.
TEST_F(CompositorMusConnectionTest, RendererWillNotSendAck) {
mus::TestWindow test_window;
- ui::PointerEvent event(ui::ET_POINTER_DOWN,
- ui::EventPointerType::POINTER_TYPE_MOUSE, gfx::Point(),
- gfx::Point(), ui::EF_NONE, 0, ui::EventTimeForNow());
+ ui::PointerEvent event(
+ ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 0,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE),
+ ui::EventTimeForNow());
scoped_refptr<TestCallback> test_callback(new TestCallback);
std::unique_ptr<base::Callback<void(EventResult)>> ack_callback(
@@ -466,9 +467,10 @@ TEST_F(CompositorMusConnectionTest, TouchEventConsumed) {
input_handler->set_state(InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED);
mus::TestWindow test_window;
- ui::PointerEvent event(ui::ET_POINTER_DOWN,
- ui::EventPointerType::POINTER_TYPE_TOUCH, gfx::Point(),
- gfx::Point(), ui::EF_NONE, 0, ui::EventTimeForNow());
+ ui::PointerEvent event(
+ ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 0,
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH),
+ ui::EventTimeForNow());
scoped_refptr<TestCallback> test_callback(new TestCallback);
std::unique_ptr<base::Callback<void(EventResult)>> ack_callback(
diff --git a/chromium/content/renderer/mus/render_widget_mus_connection.cc b/chromium/content/renderer/mus/render_widget_mus_connection.cc
index 6916b324111..b5890e5ba28 100644
--- a/chromium/content/renderer/mus/render_widget_mus_connection.cc
+++ b/chromium/content/renderer/mus/render_widget_mus_connection.cc
@@ -11,15 +11,12 @@
#include "components/mus/public/cpp/context_provider.h"
#include "components/mus/public/cpp/output_surface.h"
#include "components/mus/public/interfaces/command_buffer.mojom.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
-#include "components/mus/public/interfaces/gpu.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/renderer/mus/compositor_mus_connection.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/converters/surfaces/surfaces_utils.h"
#include "services/shell/public/cpp/connector.h"
namespace content {
@@ -49,13 +46,9 @@ std::unique_ptr<cc::OutputSurface>
RenderWidgetMusConnection::CreateOutputSurface() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!window_surface_binding_);
- mus::mojom::GpuPtr gpu_service;
- MojoShellConnection::Get()->GetConnector()->ConnectToInterface("mojo:mus",
- &gpu_service);
- mus::mojom::CommandBufferPtr cb;
- gpu_service->CreateOffscreenGLES2Context(GetProxy(&cb));
- scoped_refptr<cc::ContextProvider> context_provider(
- new mus::ContextProvider(cb.PassInterface().PassHandle()));
+ scoped_refptr<cc::ContextProvider> context_provider(new mus::ContextProvider(
+ MojoShellConnection::GetForProcess()->GetConnector()));
+
std::unique_ptr<cc::OutputSurface> surface(new mus::OutputSurface(
context_provider, mus::WindowSurface::Create(&window_surface_binding_)));
if (compositor_mus_connection_) {
@@ -100,13 +93,6 @@ bool RenderWidgetMusConnection::HasTouchEventHandlersAt(
return true;
}
-void RenderWidgetMusConnection::ObserveWheelEventAndResult(
- const blink::WebMouseWheelEvent& wheel_event,
- const gfx::Vector2dF& wheel_unused_delta,
- bool event_processed) {
- NOTIMPLEMENTED();
-}
-
void RenderWidgetMusConnection::ObserveGestureEventAndResult(
const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& wheel_unused_delta,
diff --git a/chromium/content/renderer/mus/render_widget_mus_connection.h b/chromium/content/renderer/mus/render_widget_mus_connection.h
index 4e61189fb06..bb0abe34a34 100644
--- a/chromium/content/renderer/mus/render_widget_mus_connection.h
+++ b/chromium/content/renderer/mus/render_widget_mus_connection.h
@@ -43,9 +43,6 @@ class CONTENT_EXPORT RenderWidgetMusConnection
// RenderWidgetInputHandlerDelegate implementation:
void FocusChangeComplete() override;
bool HasTouchEventHandlersAt(const gfx::Point& point) const override;
- void ObserveWheelEventAndResult(const blink::WebMouseWheelEvent& wheel_event,
- const gfx::Vector2dF& wheel_unused_delta,
- bool event_processed) override;
void ObserveGestureEventAndResult(const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& gesture_unused_delta,
bool event_processed) override;
diff --git a/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc b/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
index 83ca42443de..dd862b0e8f0 100644
--- a/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
+++ b/chromium/content/renderer/mus/render_widget_window_tree_client_factory.cc
@@ -16,6 +16,7 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/shell/public/cpp/connection.h"
#include "services/shell/public/cpp/interface_factory.h"
+#include "services/shell/public/cpp/shell_client.h"
#include "url/gurl.h"
namespace content {
@@ -23,21 +24,21 @@ namespace content {
namespace {
// This object's lifetime is managed by MojoShellConnection because it's a
-// MojoShellConnection::Listener.
+// registered with it.
class RenderWidgetWindowTreeClientFactoryImpl
- : public MojoShellConnection::Listener,
+ : public shell::ShellClient,
public shell::InterfaceFactory<
mojom::RenderWidgetWindowTreeClientFactory>,
public mojom::RenderWidgetWindowTreeClientFactory {
public:
RenderWidgetWindowTreeClientFactoryImpl() {
- DCHECK(MojoShellConnection::Get());
+ DCHECK(MojoShellConnection::GetForProcess());
}
~RenderWidgetWindowTreeClientFactoryImpl() override {}
private:
- // MojoShellConnection::Listener implementation:
+ // shell::ShellClient implementation:
bool AcceptConnection(shell::Connection* connection) override {
connection->AddInterface<mojom::RenderWidgetWindowTreeClientFactory>(this);
return true;
@@ -67,8 +68,8 @@ class RenderWidgetWindowTreeClientFactoryImpl
} // namespace
void CreateRenderWidgetWindowTreeClientFactory() {
- MojoShellConnection::Get()->AddListener(
- base::WrapUnique(new RenderWidgetWindowTreeClientFactoryImpl()));
+ MojoShellConnection::GetForProcess()->AddEmbeddedShellClient(
+ base::WrapUnique(new RenderWidgetWindowTreeClientFactoryImpl));
}
} // namespace content
diff --git a/chromium/content/renderer/notification_permission_dispatcher.cc b/chromium/content/renderer/notification_permission_dispatcher.cc
index f038b5c2dfb..0e7e402a791 100644
--- a/chromium/content/renderer/notification_permission_dispatcher.cc
+++ b/chromium/content/renderer/notification_permission_dispatcher.cc
@@ -7,12 +7,13 @@
#include <utility>
#include "base/bind.h"
-#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_frame.h"
+#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom-blink.h"
#include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/modules/notifications/WebNotificationPermissionCallback.h"
using blink::WebNotificationPermissionCallback;
@@ -29,8 +30,7 @@ void NotificationPermissionDispatcher::RequestPermission(
const blink::WebSecurityOrigin& origin,
WebNotificationPermissionCallback* callback) {
if (!permission_service_.get()) {
- render_frame()->GetServiceRegistry()->ConnectToRemoteService(
- mojo::GetProxy(&permission_service_));
+ render_frame()->GetRemoteInterfaces()->GetInterface(&permission_service_);
}
std::unique_ptr<WebNotificationPermissionCallback> owned_callback(callback);
@@ -39,6 +39,7 @@ void NotificationPermissionDispatcher::RequestPermission(
// callbacks, will be deleted before the "this" instance is deleted.
permission_service_->RequestPermission(
blink::mojom::PermissionName::NOTIFICATIONS, origin.toString().utf8(),
+ blink::WebUserGestureIndicator::isProcessingUserGesture(),
base::Bind(&NotificationPermissionDispatcher::OnPermissionRequestComplete,
base::Unretained(this),
base::Passed(std::move(owned_callback))));
@@ -55,4 +56,8 @@ void NotificationPermissionDispatcher::OnPermissionRequestComplete(
callback->permissionRequestComplete(blink_status);
}
+void NotificationPermissionDispatcher::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/notification_permission_dispatcher.h b/chromium/content/renderer/notification_permission_dispatcher.h
index 77fbb63c2a0..8b1eb58adfa 100644
--- a/chromium/content/renderer/notification_permission_dispatcher.h
+++ b/chromium/content/renderer/notification_permission_dispatcher.h
@@ -33,6 +33,9 @@ class NotificationPermissionDispatcher : public RenderFrameObserver {
blink::WebNotificationPermissionCallback* callback);
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
void OnPermissionRequestComplete(
std::unique_ptr<blink::WebNotificationPermissionCallback> callback,
blink::mojom::PermissionStatus status);
diff --git a/chromium/content/renderer/p2p/filtering_network_manager.cc b/chromium/content/renderer/p2p/filtering_network_manager.cc
index dba704a571a..4112d56f513 100644
--- a/chromium/content/renderer/p2p/filtering_network_manager.cc
+++ b/chromium/content/renderer/p2p/filtering_network_manager.cc
@@ -27,29 +27,13 @@ FilteringNetworkManager::FilteringNetworkManager(
// If the feature is not enabled, just return ALLOWED as it's requested.
if (!media_permission_) {
- initialized_ = true;
+ started_permission_check_ = true;
set_enumeration_permission(ENUMERATION_ALLOWED);
VLOG(3) << "media_permission is not passed, granting permission";
return;
}
}
-void FilteringNetworkManager::Initialize() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!initialized_);
-
- initialized_ = true;
- pending_permission_checks_ = 2;
-
- // Request for media permission asynchronously.
- media_permission_->HasPermission(
- media::MediaPermission::AUDIO_CAPTURE, requesting_origin_,
- base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
- media_permission_->HasPermission(
- media::MediaPermission::VIDEO_CAPTURE, requesting_origin_,
- base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
-}
-
FilteringNetworkManager::~FilteringNetworkManager() {
DCHECK(thread_checker_.CalledOnValidThread());
// This helps to catch the case if permission never comes back.
@@ -61,9 +45,15 @@ base::WeakPtr<FilteringNetworkManager> FilteringNetworkManager::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
+void FilteringNetworkManager::Initialize() {
+ rtc::NetworkManagerBase::Initialize();
+ if (media_permission_)
+ CheckPermission();
+}
+
void FilteringNetworkManager::StartUpdating() {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(initialized_);
+ DCHECK(started_permission_check_);
if (start_updating_time_.is_null()) {
start_updating_time_ = base::TimeTicks::Now();
@@ -101,6 +91,22 @@ bool FilteringNetworkManager::GetDefaultLocalAddress(
return network_manager_->GetDefaultLocalAddress(family, ipaddress);
}
+void FilteringNetworkManager::CheckPermission() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!started_permission_check_);
+
+ started_permission_check_ = true;
+ pending_permission_checks_ = 2;
+
+ // Request for media permission asynchronously.
+ media_permission_->HasPermission(
+ media::MediaPermission::AUDIO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
+ media_permission_->HasPermission(
+ media::MediaPermission::VIDEO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
+}
+
void FilteringNetworkManager::OnPermissionStatus(bool granted) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_GT(pending_permission_checks_, 0);
diff --git a/chromium/content/renderer/p2p/filtering_network_manager.h b/chromium/content/renderer/p2p/filtering_network_manager.h
index 7b0fca26231..01b0ccd2442 100644
--- a/chromium/content/renderer/p2p/filtering_network_manager.h
+++ b/chromium/content/renderer/p2p/filtering_network_manager.h
@@ -46,11 +46,8 @@ class FilteringNetworkManager : public rtc::NetworkManagerBase,
CONTENT_EXPORT ~FilteringNetworkManager() override;
- // Check mic/camera permission.
- // This is called by PeerConnectionDependencyFactory.
- CONTENT_EXPORT void Initialize();
-
// rtc::NetworkManager:
+ void Initialize() override;
void StartUpdating() override;
void StopUpdating() override;
void GetNetworks(NetworkList* networks) const override;
@@ -58,6 +55,9 @@ class FilteringNetworkManager : public rtc::NetworkManagerBase,
rtc::IPAddress* ipaddress) const override;
private:
+ // Check mic/camera permission.
+ void CheckPermission();
+
// Receive callback from MediaPermission when the permission status is
// available.
void OnPermissionStatus(bool granted);
@@ -110,8 +110,8 @@ class FilteringNetworkManager : public rtc::NetworkManagerBase,
// StartUpdating.
int start_count_ = 0;
- // Track whether Initialize has been called before StartUpdating.
- bool initialized_ = false;
+ // Track whether CheckPermission has been called before StartUpdating.
+ bool started_permission_check_ = false;
// Track how long it takes for client to receive SignalNetworksChanged. This
// helps to identify if the signal is delayed by permission check and increase
diff --git a/chromium/content/renderer/p2p/port_allocator.cc b/chromium/content/renderer/p2p/port_allocator.cc
index c9bc9fadf1d..00ee3beddab 100644
--- a/chromium/content/renderer/p2p/port_allocator.cc
+++ b/chromium/content/renderer/p2p/port_allocator.cc
@@ -21,14 +21,15 @@ P2PPortAllocator::P2PPortAllocator(
std::unique_ptr<rtc::NetworkManager> network_manager,
rtc::PacketSocketFactory* socket_factory,
const Config& config,
- const GURL& origin,
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ const GURL& origin)
: cricket::BasicPortAllocator(network_manager.get(), socket_factory),
network_manager_(std::move(network_manager)),
socket_dispatcher_(socket_dispatcher),
config_(config),
- origin_(origin),
- network_manager_task_runner_(task_runner) {
+ origin_(origin) {
+ DCHECK(socket_dispatcher);
+ DCHECK(network_manager_);
+ DCHECK(socket_factory);
uint32_t flags = 0;
if (!config_.enable_multiple_routes) {
flags |= cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION;
@@ -51,13 +52,11 @@ P2PPortAllocator::P2PPortAllocator(
}
}
-// TODO(guoweis): P2PPortAllocator is also deleted in the wrong thread
-// here. It's created in signaling thread, and held by webrtc::PeerConnection,
-// only used on worker thread. The destructor is invoked on signaling thread
-// again. crbug.com/535761. DeleteSoon can be removed once the bug is fixed.
-P2PPortAllocator::~P2PPortAllocator() {
- network_manager_task_runner_->DeleteSoon(FROM_HERE,
- network_manager_.release());
+P2PPortAllocator::~P2PPortAllocator() {}
+
+void P2PPortAllocator::Initialize() {
+ BasicPortAllocator::Initialize();
+ network_manager_->Initialize();
}
} // namespace content
diff --git a/chromium/content/renderer/p2p/port_allocator.h b/chromium/content/renderer/p2p/port_allocator.h
index 945b5f87e6e..f686b39643e 100644
--- a/chromium/content/renderer/p2p/port_allocator.h
+++ b/chromium/content/renderer/p2p/port_allocator.h
@@ -38,26 +38,22 @@ class P2PPortAllocator : public cricket::BasicPortAllocator {
bool enable_default_local_candidate = true;
};
- P2PPortAllocator(
- const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher,
- std::unique_ptr<rtc::NetworkManager> network_manager,
- rtc::PacketSocketFactory* socket_factory,
- const Config& config,
- const GURL& origin,
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ P2PPortAllocator(const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher,
+ std::unique_ptr<rtc::NetworkManager> network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const Config& config,
+ const GURL& origin);
~P2PPortAllocator() override;
+ // Will also initialize the network manager passed into the constructor.
+ void Initialize() override;
+
private:
std::unique_ptr<rtc::NetworkManager> network_manager_;
scoped_refptr<P2PSocketDispatcher> socket_dispatcher_;
Config config_;
GURL origin_;
- // This is the thread |network_manager_| is associated with and must be used
- // to delete |network_manager_|.
- const scoped_refptr<base::SingleThreadTaskRunner>
- network_manager_task_runner_;
-
DISALLOW_COPY_AND_ASSIGN(P2PPortAllocator);
};
diff --git a/chromium/content/renderer/pepper/message_channel.cc b/chromium/content/renderer/pepper/message_channel.cc
index f14f0041969..4566631717e 100644
--- a/chromium/content/renderer/pepper/message_channel.cc
+++ b/chromium/content/renderer/pepper/message_channel.cc
@@ -12,7 +12,6 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/pepper/host_array_buffer_var.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/pepper_try_catch.h"
#include "content/renderer/pepper/plugin_module.h"
@@ -27,20 +26,12 @@
#include "ppapi/shared_impl/var.h"
#include "ppapi/shared_impl/var_tracker.h"
#include "third_party/WebKit/public/web/WebDOMMessageEvent.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebElement.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebNode.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
-#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
#include "v8/include/v8.h"
-using ppapi::ArrayBufferVar;
using ppapi::PpapiGlobals;
using ppapi::ScopedPPVar;
using ppapi::StringVar;
-using blink::WebElement;
-using blink::WebDOMEvent;
using blink::WebDOMMessageEvent;
using blink::WebPluginContainer;
using blink::WebSerializedScriptValue;
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
index 0a4bc6e3a53..6f39f0fb7d9 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
@@ -4,6 +4,7 @@
#include "content/renderer/pepper/mock_renderer_ppapi_host.h"
+#include "content/public/renderer/render_view.h"
#include "content/renderer/pepper/fake_pepper_plugin_instance.h"
#include "ui/gfx/geometry/point.h"
@@ -16,7 +17,10 @@ MockRendererPpapiHost::MockRendererPpapiHost(RenderView* render_view,
render_view_(render_view),
pp_instance_(instance),
has_user_gesture_(false),
- plugin_instance_(new FakePepperPluginInstance) {}
+ plugin_instance_(new FakePepperPluginInstance) {
+ if (render_view)
+ render_frame_ = render_view->GetMainRenderFrame();
+}
MockRendererPpapiHost::~MockRendererPpapiHost() {}
@@ -35,6 +39,8 @@ PepperPluginInstance* MockRendererPpapiHost::GetPluginInstance(
RenderFrame* MockRendererPpapiHost::GetRenderFrameForInstance(
PP_Instance instance) const {
+ if (instance == pp_instance_)
+ return render_frame_;
return NULL;
}
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
index 84e6ff4d253..30dd766ed26 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
@@ -65,6 +65,7 @@ class MockRendererPpapiHost : public RendererPpapiHost {
ppapi::host::PpapiHost ppapi_host_;
RenderView* render_view_;
+ RenderFrame* render_frame_;
PP_Instance pp_instance_;
bool has_user_gesture_;
diff --git a/chromium/content/renderer/pepper/pepper_audio_controller.cc b/chromium/content/renderer/pepper/pepper_audio_controller.cc
new file mode 100644
index 00000000000..88d80f11bd0
--- /dev/null
+++ b/chromium/content/renderer/pepper/pepper_audio_controller.cc
@@ -0,0 +1,77 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/pepper_audio_controller.h"
+
+#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
+#include "content/renderer/pepper/ppb_audio_impl.h"
+#include "content/renderer/render_frame_impl.h"
+
+namespace content {
+
+PepperAudioController::PepperAudioController(
+ PepperPluginInstanceImpl* instance)
+ : instance_(instance) {
+ DCHECK(instance_);
+}
+
+PepperAudioController::~PepperAudioController() {
+ if (instance_)
+ OnPepperInstanceDeleted();
+}
+
+void PepperAudioController::AddInstance(PPB_Audio_Impl* audio) {
+ if (!instance_)
+ return;
+ if (ppb_audios_.count(audio))
+ return;
+
+ if (ppb_audios_.empty()) {
+ RenderFrameImpl* render_frame = instance_->render_frame();
+ if (render_frame)
+ render_frame->PepperStartsPlayback(instance_);
+ }
+
+ ppb_audios_.insert(audio);
+}
+
+void PepperAudioController::RemoveInstance(PPB_Audio_Impl* audio) {
+ if (!instance_)
+ return;
+ if (!ppb_audios_.count(audio))
+ return;
+
+ ppb_audios_.erase(audio);
+
+ if (ppb_audios_.empty())
+ NotifyPlaybackStopsOnEmpty();
+}
+
+void PepperAudioController::SetVolume(double volume) {
+ if (!instance_)
+ return;
+
+ for (auto* ppb_audio : ppb_audios_)
+ ppb_audio->SetVolume(volume);
+}
+
+void PepperAudioController::OnPepperInstanceDeleted() {
+ DCHECK(instance_);
+
+ if (!ppb_audios_.empty())
+ NotifyPlaybackStopsOnEmpty();
+
+ ppb_audios_.clear();
+ instance_ = nullptr;
+}
+
+void PepperAudioController::NotifyPlaybackStopsOnEmpty() {
+ DCHECK(instance_);
+
+ RenderFrameImpl* render_frame = instance_->render_frame();
+ if (render_frame)
+ render_frame->PepperStopsPlayback(instance_);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_audio_controller.h b/chromium/content/renderer/pepper/pepper_audio_controller.h
new file mode 100644
index 00000000000..29241ab8e63
--- /dev/null
+++ b/chromium/content/renderer/pepper/pepper_audio_controller.h
@@ -0,0 +1,57 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_
+
+#include <set>
+
+#include "base/macros.h"
+
+namespace content {
+
+class PepperPluginInstanceImpl;
+class PPB_Audio_Impl;
+
+/**
+ * This class controls all the active audio instances of a Pepper instance.
+ * This class can only be a non-shareable member of PepperPluginInstanceImpl.
+ */
+class PepperAudioController {
+ public:
+ explicit PepperAudioController(PepperPluginInstanceImpl* instance);
+ virtual ~PepperAudioController();
+
+ // Adds an audio instance to the controller.
+ void AddInstance(PPB_Audio_Impl* audio);
+
+ // Removes an audio instance from the controller.
+ void RemoveInstance(PPB_Audio_Impl* audio);
+
+ // Sets the volume of all audio instances.
+ void SetVolume(double volume);
+
+ // The pepper instance has been deleted. This method can only be called
+ // once. The controller will be invalidated after this call, and then all
+ // other methods will be no-op.
+ void OnPepperInstanceDeleted();
+
+ private:
+ // Notifies the RenderFrame that the playback has stopped. This method should
+ // only be called when |ppb_audios_| turns from non-empty to empty.
+ void NotifyPlaybackStopsOnEmpty();
+
+ // All active audio instances.
+ std::set<PPB_Audio_Impl*> ppb_audios_;
+
+ // The Pepper instance which this controller is for. Will be null after
+ // OnPepperInstanceDeleted() is called.
+ PepperPluginInstanceImpl* instance_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperAudioController);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_
diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.cc b/chromium/content/renderer/pepper/pepper_browser_connection.cc
index 43affea1374..19ba1cc7a35 100644
--- a/chromium/content/renderer/pepper/pepper_browser_connection.cc
+++ b/chromium/content/renderer/pepper/pepper_browser_connection.cc
@@ -96,4 +96,8 @@ int32_t PepperBrowserConnection::GetNextSequence() {
return ret;
}
+void PepperBrowserConnection::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.h b/chromium/content/renderer/pepper/pepper_browser_connection.h
index 6e5a3d692cb..07d1501c398 100644
--- a/chromium/content/renderer/pepper/pepper_browser_connection.h
+++ b/chromium/content/renderer/pepper/pepper_browser_connection.h
@@ -60,6 +60,9 @@ class PepperBrowserConnection
void DidDeleteInProcessInstance(PP_Instance instance);
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Message handlers.
void OnMsgCreateResourceHostsFromHostReply(
int32_t sequence_number,
diff --git a/chromium/content/renderer/pepper/pepper_compositor_host.cc b/chromium/content/renderer/pepper/pepper_compositor_host.cc
index f16ef70ea4a..c2768361c0e 100644
--- a/chromium/content/renderer/pepper/pepper_compositor_host.cc
+++ b/chromium/content/renderer/pepper/pepper_compositor_host.cc
@@ -65,7 +65,7 @@ int32_t VerifyCommittedLayer(const ppapi::CompositorLayerData* old_layer,
if (new_layer->texture) {
if (old_layer) {
// Make sure the old layer is a texture layer too.
- if (!new_layer->texture)
+ if (!old_layer->texture)
return PP_ERROR_BADARGUMENT;
// The mailbox should be same, if the resource_id is not changed.
if (new_layer->common.resource_id == old_layer->common.resource_id) {
@@ -87,7 +87,7 @@ int32_t VerifyCommittedLayer(const ppapi::CompositorLayerData* old_layer,
if (new_layer->image) {
if (old_layer) {
// Make sure the old layer is an image layer too.
- if (!new_layer->image)
+ if (!old_layer->image)
return PP_ERROR_BADARGUMENT;
// The image data resource should be same, if the resource_id is not
// changed.
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
index b70ab83c3d1..f2f8be3b2e5 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -154,9 +154,10 @@ int32_t PepperFileChooserHost::OnShow(
params.requestor = renderer_ppapi_host_->GetDocumentURL(pp_instance());
handler_ = new CompletionHandler(AsWeakPtr());
- RenderViewImpl* render_view = static_cast<RenderViewImpl*>(
- renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()));
- if (!render_view || !render_view->runFileChooser(params, handler_)) {
+ RenderFrameImpl* render_frame = static_cast<RenderFrameImpl*>(
+ renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance()));
+
+ if (!render_frame || !render_frame->runFileChooser(params, handler_)) {
delete handler_;
handler_ = NULL;
return PP_ERROR_NOACCESS;
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
index f74c0a181b3..d610636955d 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
@@ -3,10 +3,12 @@
// found in the LICENSE file.
#include <stdint.h>
+#include <tuple>
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/file_chooser_file_info.h"
#include "content/public/common/file_chooser_params.h"
@@ -91,11 +93,11 @@ TEST_F(PepperFileChooserHostTest, Show) {
// The render view should have sent a chooser request to the browser
// (caught by the render thread's test message sink).
const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
- ViewHostMsg_RunFileChooser::ID);
+ FrameHostMsg_RunFileChooser::ID);
ASSERT_TRUE(msg);
- ViewHostMsg_RunFileChooser::Schema::Param call_msg_param;
- ASSERT_TRUE(ViewHostMsg_RunFileChooser::Read(msg, &call_msg_param));
- const FileChooserParams& chooser_params = base::get<0>(call_msg_param);
+ FrameHostMsg_RunFileChooser::Schema::Param call_msg_param;
+ ASSERT_TRUE(FrameHostMsg_RunFileChooser::Read(msg, &call_msg_param));
+ const FileChooserParams& chooser_params = std::get<0>(call_msg_param);
// Basic validation of request.
EXPECT_EQ(FileChooserParams::Open, chooser_params.mode);
@@ -109,10 +111,11 @@ TEST_F(PepperFileChooserHostTest, Show) {
selected_info.file_path = base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo"));
std::vector<content::FileChooserFileInfo> selected_info_vector;
selected_info_vector.push_back(selected_info);
- RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
- ViewMsg_RunFileChooserResponse response(view_impl->GetRoutingID(),
- selected_info_vector);
- EXPECT_TRUE(view_impl->OnMessageReceived(response));
+ RenderFrameImpl* frame_impl =
+ static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame());
+ FrameMsg_RunFileChooserResponse response(frame_impl->GetRoutingID(),
+ selected_info_vector);
+ EXPECT_TRUE(frame_impl->OnMessageReceived(response));
// This should have sent the Pepper reply to our test sink.
ppapi::proxy::ResourceMessageReplyParams reply_params;
@@ -127,7 +130,7 @@ TEST_F(PepperFileChooserHostTest, Show) {
ASSERT_TRUE(
PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param));
const std::vector<ppapi::FileRefCreateInfo>& chooser_results =
- base::get<0>(reply_msg_param);
+ std::get<0>(reply_msg_param);
ASSERT_EQ(1u, chooser_results.size());
EXPECT_EQ(FilePathToUTF8(selected_info.display_name),
chooser_results[0].display_name);
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
index 478e90536d7..41c82fca255 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -383,8 +383,6 @@ void PepperGraphics2DHost::ViewInitiatedPaint() {
}
}
-void PepperGraphics2DHost::SetScale(float scale) { scale_ = scale; }
-
float PepperGraphics2DHost::GetScale() const { return scale_; }
bool PepperGraphics2DHost::IsAlwaysOpaque() const { return is_always_opaque_; }
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
index 6fb01c29e8f..e50b095d8c1 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
@@ -85,7 +85,6 @@ class CONTENT_EXPORT PepperGraphics2DHost
// These messages are used to send Flush callbacks to the plugin.
void ViewInitiatedPaint();
- void SetScale(float scale);
float GetScale() const;
void SetLayerTransform(float scale, const PP_Point& transform);
bool IsAlwaysOpaque() const;
diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.cc b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
index 1b21f75c920..42abb0802af 100644
--- a/chromium/content/renderer/pepper/pepper_media_device_manager.cc
+++ b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
@@ -61,12 +61,9 @@ int PepperMediaDeviceManager::EnumerateDevices(
PepperMediaDeviceManager::FromPepperDeviceType(type),
url::Origin(document_url.GetOrigin()));
#else
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated,
- AsWeakPtr(),
- request_id,
- StreamDeviceInfoArray()));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated,
+ AsWeakPtr(), request_id, StreamDeviceInfoArray()));
#endif
return request_id;
@@ -109,11 +106,9 @@ int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type,
PepperMediaDeviceManager::FromPepperDeviceType(type),
url::Origin(document_url.GetOrigin()));
#else
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
- AsWeakPtr(),
- request_id));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
+ AsWeakPtr(), request_id));
#endif
return request_id;
@@ -255,4 +250,8 @@ MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher()
return dispatcher;
}
+void PepperMediaDeviceManager::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.h b/chromium/content/renderer/pepper/pepper_media_device_manager.h
index 90d6dc09dcf..e0343bbd197 100644
--- a/chromium/content/renderer/pepper/pepper_media_device_manager.h
+++ b/chromium/content/renderer/pepper/pepper_media_device_manager.h
@@ -81,6 +81,9 @@ class PepperMediaDeviceManager
private:
explicit PepperMediaDeviceManager(RenderFrame* render_frame);
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
// Called by StopEnumerateDevices() after returing to the event loop, to avoid
// a reentrancy problem.
void StopEnumerateDevicesDelayed(int request_id);
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
index 1e9c74cc7e5..a8e7c433668 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -60,6 +60,17 @@ bool PepperPlatformAudioOutput::StopPlayback() {
return false;
}
+bool PepperPlatformAudioOutput::SetVolume(double volume) {
+ if (ipc_) {
+ io_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&PepperPlatformAudioOutput::SetVolumeOnIOThread,
+ this, volume));
+ return true;
+ }
+ return false;
+}
+
void PepperPlatformAudioOutput::ShutDown() {
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
@@ -156,6 +167,12 @@ void PepperPlatformAudioOutput::StartPlaybackOnIOThread() {
ipc_->PlayStream();
}
+void PepperPlatformAudioOutput::SetVolumeOnIOThread(double volume) {
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->SetVolume(volume);
+}
+
void PepperPlatformAudioOutput::StopPlaybackOnIOThread() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (ipc_)
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.h b/chromium/content/renderer/pepper/pepper_platform_audio_output.h
index ea8771d6f90..439dc2b7dc2 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output.h
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.h
@@ -43,6 +43,10 @@ class PepperPlatformAudioOutput
// is created or after the stream is closed.
bool StopPlayback();
+ // Sets the volume. Returns false on error or if called before the stream
+ // is created or after the stream is closed.
+ bool SetVolume(double volume);
+
// Closes the stream. Make sure to call this before the object is
// destructed.
void ShutDown();
@@ -74,6 +78,7 @@ class PepperPlatformAudioOutput
void InitializeOnIOThread(const media::AudioParameters& params);
void StartPlaybackOnIOThread();
void StopPlaybackOnIOThread();
+ void SetVolumeOnIOThread(double volume);
void ShutDownOnIOThread();
// The client to notify when the stream is created. THIS MUST ONLY BE
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 8810686bb43..2dfd47b0822 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -35,6 +35,7 @@
#include "content/renderer/pepper/host_dispatcher_wrapper.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/message_channel.h"
+#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/pepper_browser_connection.h"
#include "content/renderer/pepper/pepper_compositor_host.h"
#include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
@@ -529,6 +530,7 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
isolate_(v8::Isolate::GetCurrent()),
is_deleted_(false),
initialized_(false),
+ audio_controller_(new PepperAudioController(this)),
view_change_weak_ptr_factory_(this),
weak_factory_(this) {
pp_instance_ = HostGlobals::Get()->AddInstance(this);
@@ -585,6 +587,8 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
if (TrackedCallback::IsPending(lock_mouse_callback_))
lock_mouse_callback_->Abort();
+ audio_controller_->OnPepperInstanceDeleted();
+
if (render_frame_)
render_frame_->PepperInstanceDeleted(this);
@@ -684,7 +688,7 @@ void PepperPluginInstanceImpl::Delete() {
// Force-unbind any Graphics. In the case of Graphics2D, if the plugin
// leaks the graphics 2D, it may actually get cleaned up after our
- // destruction, so we need its pointers to be up-to-date.
+ // destruction, so we need its pointers to be up to date.
BindGraphics(pp_instance(), 0);
container_ = NULL;
}
@@ -756,22 +760,63 @@ void PepperPluginInstanceImpl::ScrollRect(int dx,
}
}
-void PepperPluginInstanceImpl::CommitBackingTexture() {
+void PepperPluginInstanceImpl::CommitTextureMailbox(
+ const cc::TextureMailbox& texture_mailbox) {
+ if (committed_texture_.IsValid() && !IsTextureInUse(committed_texture_)) {
+ committed_texture_graphics_3d_->ReturnFrontBuffer(
+ committed_texture_.mailbox(), committed_texture_consumed_sync_token_,
+ false);
+ }
+
+ committed_texture_ = texture_mailbox;
+ committed_texture_graphics_3d_ = bound_graphics_3d_;
+ committed_texture_consumed_sync_token_ = gpu::SyncToken();
+
if (!texture_layer_) {
UpdateLayer(true);
return;
}
- gpu::Mailbox mailbox;
- gpu::SyncToken sync_token;
- bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token);
- DCHECK(!mailbox.IsZero());
- DCHECK(sync_token.HasData());
- texture_layer_->SetTextureMailboxWithoutReleaseCallback(
- cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D));
+ PassCommittedTextureToTextureLayer();
texture_layer_->SetNeedsDisplay();
}
+void PepperPluginInstanceImpl::PassCommittedTextureToTextureLayer() {
+ DCHECK(bound_graphics_3d_);
+
+ if (!committed_texture_.IsValid())
+ return;
+
+ std::unique_ptr<cc::SingleReleaseCallback> callback(
+ cc::SingleReleaseCallback::Create(base::Bind(
+ &PepperPluginInstanceImpl::FinishedConsumingCommittedTexture,
+ weak_factory_.GetWeakPtr(), committed_texture_,
+ committed_texture_graphics_3d_)));
+
+ IncrementTextureReferenceCount(committed_texture_);
+ texture_layer_->SetTextureMailbox(committed_texture_, std::move(callback));
+}
+
+void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture(
+ const cc::TextureMailbox& texture_mailbox,
+ scoped_refptr<PPB_Graphics3D_Impl> graphics_3d,
+ const gpu::SyncToken& sync_token,
+ bool is_lost) {
+ bool removed = DecrementTextureReferenceCount(texture_mailbox);
+ bool is_committed_texture =
+ committed_texture_.mailbox() == texture_mailbox.mailbox();
+
+ if (is_committed_texture && !is_lost) {
+ committed_texture_consumed_sync_token_ = sync_token;
+ return;
+ }
+
+ if (removed && !is_committed_texture) {
+ graphics_3d->ReturnFrontBuffer(texture_mailbox.mailbox(), sync_token,
+ is_lost);
+ }
+}
+
void PepperPluginInstanceImpl::InstanceCrashed() {
// Force free all resources and vars.
HostGlobals::Get()->InstanceCrashed(pp_instance());
@@ -843,6 +888,14 @@ bool PepperPluginInstanceImpl::Initialize(
if (message_channel_)
message_channel_->Start();
}
+
+ if (success &&
+ render_frame_ &&
+ render_frame_->render_accessibility() &&
+ LoadPdfInterface()) {
+ plugin_pdf_interface_->EnableAccessibility(pp_instance());
+ }
+
initialized_ = success;
return success;
}
@@ -1216,8 +1269,7 @@ PP_Var PepperPluginInstanceImpl::GetInstanceObject(v8::Isolate* isolate) {
void PepperPluginInstanceImpl::ViewChanged(
const gfx::Rect& window,
const gfx::Rect& clip,
- const gfx::Rect& unobscured,
- const std::vector<gfx::Rect>& cut_outs_rects) {
+ const gfx::Rect& unobscured) {
// WebKit can give weird (x,y) positions for empty clip rects (since the
// position technically doesn't matter). But we want to make these
// consistent since this is given to the plugin, so force everything to 0
@@ -1228,8 +1280,6 @@ void PepperPluginInstanceImpl::ViewChanged(
unobscured_rect_ = unobscured;
- cut_outs_rects_ = cut_outs_rects;
-
view_data_.rect = PP_FromGfxRect(window);
view_data_.clip_rect = PP_FromGfxRect(clip);
view_data_.device_scale = container_->deviceScaleFactor();
@@ -1251,9 +1301,7 @@ void PepperPluginInstanceImpl::ViewChanged(
scroll_offset.height());
if (desired_fullscreen_state_ || view_data_.is_fullscreen) {
- WebElement element = container_->element();
- WebDocument document = element.document();
- bool is_fullscreen_element = (element == document.fullScreenElement());
+ bool is_fullscreen_element = container_->isFullscreenElement();
if (!view_data_.is_fullscreen && desired_fullscreen_state_ &&
render_frame()->GetRenderWidget()->is_fullscreen_granted() &&
is_fullscreen_element) {
@@ -1424,12 +1472,13 @@ bool PepperPluginInstanceImpl::StartFind(const base::string16& search_text,
PP_FromBool(case_sensitive)));
}
-void PepperPluginInstanceImpl::SelectFindResult(bool forward) {
+void PepperPluginInstanceImpl::SelectFindResult(bool forward, int identifier) {
// Keep a reference on the stack. See NOTE above.
scoped_refptr<PepperPluginInstanceImpl> ref(this);
- if (LoadFindInterface())
- plugin_find_interface_->SelectFindResult(pp_instance(),
- PP_FromBool(forward));
+ if (!LoadFindInterface())
+ return;
+ find_identifier_ = identifier;
+ plugin_find_interface_->SelectFindResult(pp_instance(), PP_FromBool(forward));
}
void PepperPluginInstanceImpl::StopFind() {
@@ -1921,9 +1970,9 @@ bool PepperPluginInstanceImpl::SetFullscreen(bool fullscreen) {
// so we will tweak plugin's attributes to support the expected behavior.
KeepSizeAttributesBeforeFullscreen();
SetSizeAttributesForFullscreen();
- container_->element().requestFullScreen();
+ container_->requestFullscreen();
} else {
- container_->document().cancelFullScreen();
+ container_->cancelFullscreen();
}
return true;
}
@@ -2003,12 +2052,7 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
if (!container_)
return;
- gpu::Mailbox mailbox;
- gpu::SyncToken sync_token;
- if (bound_graphics_3d_.get()) {
- bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token);
- }
- bool want_3d_layer = !mailbox.IsZero() && sync_token.HasData();
+ bool want_3d_layer = !!bound_graphics_3d_.get();
bool want_2d_layer = !!bound_graphics_2d_platform_;
bool want_texture_layer = want_3d_layer || want_2d_layer;
bool want_compositor_layer = !!bound_compositor_;
@@ -2047,8 +2091,8 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) {
DCHECK(bound_graphics_3d_.get());
texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
opaque = bound_graphics_3d_->IsOpaque();
- texture_layer_->SetTextureMailboxWithoutReleaseCallback(
- cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D));
+
+ PassCommittedTextureToTextureLayer();
} else {
DCHECK(bound_graphics_2d_platform_);
texture_layer_ = cc::TextureLayer::CreateForMailbox(this);
@@ -3340,4 +3384,47 @@ void PepperPluginInstanceImpl::ConvertDIPToViewport(gfx::Rect* rect) const {
rect->set_height(rect->height() / viewport_to_dip_scale_);
}
+void PepperPluginInstanceImpl::IncrementTextureReferenceCount(
+ const cc::TextureMailbox& mailbox) {
+ auto it =
+ std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
+ [&mailbox](const TextureMailboxRefCount& ref_count) {
+ return ref_count.first.mailbox() == mailbox.mailbox();
+ });
+ if (it == texture_ref_counts_.end()) {
+ texture_ref_counts_.push_back(std::make_pair(mailbox, 1));
+ return;
+ }
+
+ it->second++;
+}
+
+bool PepperPluginInstanceImpl::DecrementTextureReferenceCount(
+ const cc::TextureMailbox& mailbox) {
+ auto it =
+ std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
+ [&mailbox](const TextureMailboxRefCount& ref_count) {
+ return ref_count.first.mailbox() == mailbox.mailbox();
+ });
+ DCHECK(it != texture_ref_counts_.end());
+
+ if (it->second == 1) {
+ texture_ref_counts_.erase(it);
+ return true;
+ }
+
+ it->second--;
+ return false;
+}
+
+bool PepperPluginInstanceImpl::IsTextureInUse(
+ const cc::TextureMailbox& mailbox) const {
+ auto it =
+ std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(),
+ [&mailbox](const TextureMailboxRefCount& ref_count) {
+ return ref_count.first.mailbox() == mailbox.mailbox();
+ });
+ return it != texture_ref_counts_.end();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
index dd53679cc79..f3089f05042 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -24,6 +24,7 @@
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "cc/layers/texture_layer_client.h"
+#include "cc/resources/texture_mailbox.h"
#include "content/common/content_export.h"
#include "content/public/renderer/pepper_plugin_instance.h"
#include "content/public/renderer/plugin_instance_throttler.h"
@@ -105,6 +106,7 @@ namespace content {
class ContentDecryptorDelegate;
class FullscreenContainer;
class MessageChannel;
+class PepperAudioController;
class PepperCompositorHost;
class PepperGraphics2DHost;
class PluginInstanceThrottlerImpl;
@@ -197,9 +199,18 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// slow path can also be triggered if there is an overlapping frame.
void ScrollRect(int dx, int dy, const gfx::Rect& rect);
- // Commit the backing texture to the screen once the side effects some
- // rendering up to an offscreen SwapBuffers are visible.
- void CommitBackingTexture();
+ // Commit the texture mailbox to the screen.
+ void CommitTextureMailbox(const cc::TextureMailbox& texture_mailbox);
+
+ // Passes the committed texture to |texture_layer_| and marks it as in use.
+ void PassCommittedTextureToTextureLayer();
+
+ // Callback when the compositor is finished consuming the committed texture.
+ void FinishedConsumingCommittedTexture(
+ const cc::TextureMailbox& texture_mailbox,
+ scoped_refptr<PPB_Graphics3D_Impl> graphics_3d,
+ const gpu::SyncToken& sync_token,
+ bool is_lost);
// Called when the out-of-process plugin implementing this instance crashed.
void InstanceCrashed();
@@ -219,8 +230,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
PP_Var GetInstanceObject(v8::Isolate* isolate);
void ViewChanged(const gfx::Rect& window,
const gfx::Rect& clip,
- const gfx::Rect& unobscured,
- const std::vector<gfx::Rect>& cut_outs_rects);
+ const gfx::Rect& unobscured);
// Handlers for composition events.
bool HandleCompositionStart(const base::string16& text);
@@ -259,7 +269,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
bool StartFind(const base::string16& search_text,
bool case_sensitive,
int identifier);
- void SelectFindResult(bool forward);
+ void SelectFindResult(bool forward, int identifier);
void StopFind();
bool SupportsPrintInterface();
@@ -548,6 +558,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
void OnThrottleStateChange() override;
void OnHiddenForPlaceholder(bool hidden) override;
+ PepperAudioController& audio_controller() {
+ return *audio_controller_;
+ }
+
private:
friend class base::RefCounted<PepperPluginInstanceImpl>;
friend class PpapiPluginInstanceTest;
@@ -702,6 +716,28 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
void ConvertRectToDIP(PP_Rect* rect) const;
void ConvertDIPToViewport(gfx::Rect* rect) const;
+ // Each time CommitTextureMailbox() is called, this instance is given
+ // ownership
+ // of a cc::TextureMailbox. This instance always needs to hold on to the most
+ // recently committed cc::TextureMailbox, since UpdateLayer() might require
+ // it.
+ // Since it is possible for a cc::TextureMailbox to be passed to
+ // texture_layer_ more than once, a reference counting mechanism is necessary
+ // to ensure that a cc::TextureMailbox isn't returned until all copies of it
+ // have been released by texture_layer_.
+ //
+ // This method should be called each time a cc::TextureMailbox is passed to
+ // |texture_layer_|. It increments an internal reference count.
+ void IncrementTextureReferenceCount(const cc::TextureMailbox& mailbox);
+
+ // This method should be called each time |texture_layer_| finishes consuming
+ // a cc::TextureMailbox. It decrements an internal reference count. Returns
+ // whether the last reference was removed.
+ bool DecrementTextureReferenceCount(const cc::TextureMailbox& mailbox);
+
+ // Whether a given cc::TextureMailbox is in use by |texture_layer_|.
+ bool IsTextureInUse(const cc::TextureMailbox& mailbox) const;
+
RenderFrameImpl* render_frame_;
scoped_refptr<PluginModule> module_;
std::unique_ptr<ppapi::PPP_Instance_Combined> instance_interface_;
@@ -831,10 +867,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// Set to true if this plugin thinks it will always be on top. This allows us
// to use a more optimized painting path in some cases.
bool always_on_top_;
- // Even if |always_on_top_| is true, the plugin is not fully visible if there
- // are some cut-out areas (occupied by iframes higher in the stacking order).
- // This information is used in the optimized painting path.
- std::vector<gfx::Rect> cut_outs_rects_;
// Implementation of PPB_FlashFullscreen.
@@ -932,8 +964,27 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// The text that is currently selected in the plugin.
base::string16 selected_text_;
+ // The most recently committed texture. This is kept around in case the layer
+ // needs to be regenerated.
+ cc::TextureMailbox committed_texture_;
+
+ // The Graphics3D that produced the most recently committed texture.
+ scoped_refptr<PPB_Graphics3D_Impl> committed_texture_graphics_3d_;
+
+ gpu::SyncToken committed_texture_consumed_sync_token_;
+
+ // Holds the number of references |texture_layer_| has to any given
+ // cc::TextureMailbox.
+ // We expect there to be no more than 10 textures in use at a time. A
+ // std::vector will have better performance than a std::map.
+ using TextureMailboxRefCount = std::pair<cc::TextureMailbox, int>;
+ std::vector<TextureMailboxRefCount> texture_ref_counts_;
+
bool initialized_;
+ // The controller for all active audios of this pepper instance.
+ std::unique_ptr<PepperAudioController> audio_controller_;
+
// We use a weak ptr factory for scheduling DidChangeView events so that we
// can tell whether updates are pending and consolidate them. When there's
// already a weak ptr pending (HasWeakPtrs is true), code should update the
diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
index ac34ce9ca66..d8b75dda4aa 100644
--- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc
+++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
@@ -264,7 +264,9 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen(
// The requests from the plugins with private permission which can bypass same
// origin must skip the ServiceWorker.
web_request.setSkipServiceWorker(
- host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE));
+ host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)
+ ? blink::WebURLRequest::SkipServiceWorker::All
+ : blink::WebURLRequest::SkipServiceWorker::None);
WebURLLoaderOptions options;
if (has_universal_access_) {
diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
index 00fbe5d631b..3ca1c3b1b9f 100644
--- a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
@@ -149,7 +149,10 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize(
// it is okay to immediately send IPC messages.
if (command_buffer->channel()) {
decoder_.reset(new media::GpuVideoDecodeAcceleratorHost(command_buffer));
- if (decoder_->Initialize(profile_, this)) {
+ media::VideoDecodeAccelerator::Config vda_config(profile_);
+ vda_config.supported_output_formats.assign(
+ {media::PIXEL_FORMAT_XRGB, media::PIXEL_FORMAT_ARGB});
+ if (decoder_->Initialize(vda_config, this)) {
initialized_ = true;
return PP_OK;
}
@@ -351,6 +354,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgReset(
void PepperVideoDecoderHost::ProvidePictureBuffers(
uint32_t requested_num_of_buffers,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) {
diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.h b/chromium/content/renderer/pepper/pepper_video_decoder_host.h
index 308ba447598..e0f383a651b 100644
--- a/chromium/content/renderer/pepper/pepper_video_decoder_host.h
+++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.h
@@ -73,6 +73,7 @@ class CONTENT_EXPORT PepperVideoDecoderHost
// media::VideoDecodeAccelerator::Client implementation.
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
index 8438c0f51d3..0d0997b5047 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -441,12 +441,14 @@ void PepperVideoEncoderHost::RequireBitstreamBuffers(
}
void PepperVideoEncoderHost::BitstreamBufferReady(int32_t buffer_id,
- size_t payload_size,
- bool key_frame) {
+ size_t payload_size,
+ bool key_frame,
+ base::TimeDelta /* timestamp */) {
DCHECK(RenderThreadImpl::current());
DCHECK(shm_buffers_[buffer_id]->in_use);
shm_buffers_[buffer_id]->in_use = false;
+ // TODO: Pass timestamp. Tracked in crbug/613984.
host()->SendUnsolicitedReply(
pp_resource(),
PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
@@ -527,10 +529,10 @@ bool PepperVideoEncoderHost::EnsureGpuChannel() {
return false;
command_buffer_ = gpu::CommandBufferProxyImpl::Create(
- std::move(channel), gpu::kNullSurfaceHandle, gfx::Size(), nullptr,
+ std::move(channel), gpu::kNullSurfaceHandle, nullptr,
gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL,
gpu::gles2::ContextCreationAttribHelper(), GURL::EmptyGURL(),
- gfx::PreferIntegratedGpu, base::ThreadTaskRunnerHandle::Get());
+ base::ThreadTaskRunnerHandle::Get());
if (!command_buffer_) {
Close();
return false;
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.h b/chromium/content/renderer/pepper/pepper_video_encoder_host.h
index 53b95069119..d3f8e2a4eb0 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.h
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.h
@@ -71,7 +71,8 @@ class CONTENT_EXPORT PepperVideoEncoderHost
size_t output_buffer_size) override;
void BitstreamBufferReady(int32_t bitstream_buffer_id,
size_t payload_size,
- bool key_frame) override;
+ bool key_frame,
+ base::TimeDelta timestamp) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
// ResourceHost implementation.
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
index 813820319f5..3949db81188 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -9,7 +9,9 @@
#include <utility>
#include "base/debug/crash_logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/message_channel.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
@@ -155,7 +157,7 @@ void PepperWebPluginImpl::destroy() {
instance_ = nullptr;
}
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
v8::Local<v8::Object> PepperWebPluginImpl::v8ScriptableObject(
@@ -199,12 +201,8 @@ void PepperWebPluginImpl::updateGeometry(
const WebVector<WebRect>& cut_outs_rects,
bool is_visible) {
plugin_rect_ = window_rect;
- if (instance_ && !instance_->FlashIsFullscreenOrPending()) {
- std::vector<gfx::Rect> cut_outs;
- for (size_t i = 0; i < cut_outs_rects.size(); ++i)
- cut_outs.push_back(cut_outs_rects[i]);
- instance_->ViewChanged(plugin_rect_, clip_rect, unobscured_rect, cut_outs);
- }
+ if (instance_ && !instance_->FlashIsFullscreenOrPending())
+ instance_->ViewChanged(plugin_rect_, clip_rect, unobscured_rect);
}
void PepperWebPluginImpl::updateFocus(bool focused,
@@ -271,8 +269,8 @@ bool PepperWebPluginImpl::startFind(const blink::WebString& search_text,
return instance_->StartFind(search_text, case_sensitive, identifier);
}
-void PepperWebPluginImpl::selectFindResult(bool forward) {
- instance_->SelectFindResult(forward);
+void PepperWebPluginImpl::selectFindResult(bool forward, int identifier) {
+ instance_->SelectFindResult(forward, identifier);
}
void PepperWebPluginImpl::stopFind() { instance_->StopFind(); }
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.h b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
index 49a0832c5ae..3de02b80c1a 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.h
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
@@ -70,7 +70,7 @@ class PepperWebPluginImpl : public blink::WebPlugin {
bool startFind(const blink::WebString& search_text,
bool case_sensitive,
int identifier) override;
- void selectFindResult(bool forward) override;
+ void selectFindResult(bool forward, int identifier) override;
void stopFind() override;
bool supportsPaginatedPrint() override;
bool isPrintScalingDisabled() override;
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
index 36d65e3f8fc..1879b7e9fe2 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
@@ -7,9 +7,11 @@
#include <string>
#include "base/command_line.h"
-#include "base/message_loop/message_loop.h"
+#include "base/location.h"
#include "base/metrics/histogram.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "content/common/frame_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
@@ -66,6 +68,10 @@ bool PluginPowerSaverHelper::OnMessageReceived(const IPC::Message& message) {
return handled;
}
+void PluginPowerSaverHelper::OnDestruct() {
+ delete this;
+}
+
void PluginPowerSaverHelper::OnUpdatePluginContentOriginWhitelist(
const std::set<url::Origin>& origin_whitelist) {
origin_whitelist_ = origin_whitelist;
@@ -76,8 +82,8 @@ void PluginPowerSaverHelper::OnUpdatePluginContentOriginWhitelist(
if (origin_whitelist.count(it->content_origin)) {
// Because the unthrottle callback may register another peripheral plugin
// and invalidate our iterator, we cannot run it synchronously.
- base::MessageLoop::current()->PostTask(FROM_HERE,
- it->unthrottle_callback);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ it->unthrottle_callback);
it = peripheral_plugins_.erase(it);
} else {
++it;
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.h b/chromium/content/renderer/pepper/plugin_power_saver_helper.h
index 2f3bb442657..0de22ddf3b9 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper.h
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.h
@@ -57,6 +57,7 @@ class CONTENT_EXPORT PluginPowerSaverHelper : public RenderFrameObserver {
void DidCommitProvisionalLoad(bool is_new_navigation,
bool is_same_page_navigation) override;
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
void OnUpdatePluginContentOriginWhitelist(
const std::set<url::Origin>& origin_whitelist);
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
index d701c31b251..35b8388f88c 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
+
#include "base/macros.h"
#include "base/run_loop.h"
#include "content/common/frame_messages.h"
@@ -64,7 +66,7 @@ TEST_F(PluginPowerSaverHelperTest, TemporaryOriginWhitelist) {
FrameHostMsg_PluginContentOriginAllowed::Param params;
FrameHostMsg_PluginContentOriginAllowed::Read(msg, &params);
EXPECT_TRUE(url::Origin(GURL("http://other.com"))
- .IsSameOriginWith(base::get<0>(params)));
+ .IsSameOriginWith(std::get<0>(params)));
}
TEST_F(PluginPowerSaverHelperTest, UnthrottleOnExPostFactoWhitelist) {
diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.cc b/chromium/content/renderer/pepper/ppb_audio_impl.cc
index 98bf7637f4a..43426b5b5fa 100644
--- a/chromium/content/renderer/pepper/ppb_audio_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_audio_impl.cc
@@ -5,11 +5,11 @@
#include "content/renderer/pepper/ppb_audio_impl.h"
#include "base/logging.h"
+#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/pepper_platform_audio_output.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/render_frame_impl.h"
-#include "content/renderer/render_view_impl.h"
#include "media/audio/audio_output_controller.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/ppb_audio.h"
@@ -44,8 +44,11 @@ PPB_Audio_Impl::PPB_Audio_Impl(PP_Instance instance)
PPB_Audio_Impl::~PPB_Audio_Impl() {
PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>(
PepperPluginInstance::Get(pp_instance()));
- if (instance && instance->throttler()) {
- instance->throttler()->RemoveObserver(this);
+ if (instance) {
+ if (instance->throttler()) {
+ instance->throttler()->RemoveObserver(this);
+ }
+ instance->audio_controller().RemoveInstance(this);
}
// Calling ShutDown() makes sure StreamCreated cannot be called anymore and
@@ -83,6 +86,9 @@ PP_Bool PPB_Audio_Impl::StartPlayback() {
return PP_TRUE;
}
+ if (instance)
+ instance->audio_controller().AddInstance(this);
+
SetStartPlaybackState();
return PP_FromBool(audio_->StartPlayback());
}
@@ -97,6 +103,11 @@ PP_Bool PPB_Audio_Impl::StopPlayback() {
StartDeferredPlayback();
}
+ PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>(
+ PepperPluginInstance::Get(pp_instance()));
+ if (instance)
+ instance->audio_controller().RemoveInstance(this);
+
if (!playing())
return PP_TRUE;
if (!audio_->StopPlayback())
@@ -173,8 +184,17 @@ void PPB_Audio_Impl::StartDeferredPlayback() {
DCHECK(playback_throttled_);
playback_throttled_ = false;
+ PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>(
+ PepperPluginInstance::Get(pp_instance()));
+ if (instance)
+ instance->audio_controller().AddInstance(this);
+
SetStartPlaybackState();
audio_->StartPlayback();
}
+void PPB_Audio_Impl::SetVolume(double volume) {
+ if (audio_)
+ audio_->SetVolume(volume);
+}
} // namespace content
diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.h b/chromium/content/renderer/pepper/ppb_audio_impl.h
index 311dfb9306c..e0618ffb29d 100644
--- a/chromium/content/renderer/pepper/ppb_audio_impl.h
+++ b/chromium/content/renderer/pepper/ppb_audio_impl.h
@@ -50,6 +50,8 @@ class PPB_Audio_Impl : public ppapi::Resource,
int32_t GetSharedMemory(base::SharedMemory** shm,
uint32_t* shm_size) override;
+ void SetVolume(double volume);
+
private:
~PPB_Audio_Impl() override;
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
index a908b6fbe0f..5e0b5f32641 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -28,6 +28,7 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
+#include "third_party/khronos/GLES2/gl2.h"
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Graphics3D_API;
@@ -114,6 +115,22 @@ void PPB_Graphics3D_Impl::EnsureWorkVisible() {
command_buffer_->EnsureWorkVisible();
}
+void PPB_Graphics3D_Impl::TakeFrontBuffer() {
+ if (!taken_front_buffer_.IsZero()) {
+ DLOG(ERROR)
+ << "TakeFrontBuffer should only be called once before DoSwapBuffers";
+ return;
+ }
+ taken_front_buffer_ = GenerateMailbox();
+ command_buffer_->TakeFrontBuffer(taken_front_buffer_);
+}
+
+void PPB_Graphics3D_Impl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+ const gpu::SyncToken& sync_token,
+ bool is_lost) {
+ command_buffer_->ReturnFrontBuffer(mailbox, sync_token, is_lost);
+}
+
bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
bound_to_instance_ = bind;
return true;
@@ -143,8 +160,10 @@ gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() {
int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token) {
DCHECK(command_buffer_);
- if (sync_token.HasData())
- sync_token_ = sync_token;
+ if (taken_front_buffer_.IsZero()) {
+ DLOG(ERROR) << "TakeFrontBuffer should be called before DoSwapBuffers";
+ return PP_ERROR_FAILED;
+ }
if (bound_to_instance_) {
// If we are bound to the instance, we need to ask the compositor
@@ -154,14 +173,18 @@ int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token) {
//
// Don't need to check for NULL from GetPluginInstance since when we're
// bound, we know our instance is valid.
- HostGlobals::Get()->GetInstance(pp_instance())->CommitBackingTexture();
+ cc::TextureMailbox texture_mailbox(taken_front_buffer_, sync_token,
+ GL_TEXTURE_2D);
+ taken_front_buffer_.SetZero();
+ HostGlobals::Get()
+ ->GetInstance(pp_instance())
+ ->CommitTextureMailbox(texture_mailbox);
commit_pending_ = true;
} else {
// Wait for the command to complete on the GPU to allow for throttling.
command_buffer_->SignalSyncToken(
- sync_token_,
- base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
- weak_ptr_factory_.GetWeakPtr()));
+ sync_token, base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
+ weak_ptr_factory_.GetWeakPtr()));
}
return PP_OK_COMPLETIONPENDING;
@@ -202,9 +225,9 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
if (!channel)
return false;
- gfx::Size surface_size;
+ gpu::gles2::ContextCreationAttribHelper attrib_helper;
std::vector<int32_t> attribs;
- gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+ attrib_helper.gpu_preference = gl::PreferDiscreteGpu;
// TODO(alokp): Change CommandBufferProxyImpl::Create()
// interface to accept width and height in the attrib_list so that
// we do not need to filter for width and height here.
@@ -213,16 +236,16 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
attr += 2) {
switch (attr[0]) {
case PP_GRAPHICS3DATTRIB_WIDTH:
- surface_size.set_width(attr[1]);
+ attrib_helper.offscreen_framebuffer_size.set_width(attr[1]);
break;
case PP_GRAPHICS3DATTRIB_HEIGHT:
- surface_size.set_height(attr[1]);
+ attrib_helper.offscreen_framebuffer_size.set_height(attr[1]);
break;
case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
- gpu_preference =
+ attrib_helper.gpu_preference =
(attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER)
- ? gfx::PreferIntegratedGpu
- : gfx::PreferDiscreteGpu;
+ ? gl::PreferIntegratedGpu
+ : gl::PreferDiscreteGpu;
break;
case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
has_alpha_ = attr[1] > 0;
@@ -235,7 +258,6 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
}
attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
}
- gpu::gles2::ContextCreationAttribHelper attrib_helper;
if (!attrib_helper.Parse(attribs))
return false;
@@ -247,10 +269,9 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
}
command_buffer_ = gpu::CommandBufferProxyImpl::Create(
- std::move(channel), gpu::kNullSurfaceHandle, surface_size, share_buffer,
- gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL,
- attrib_helper, GURL::EmptyGURL(), gpu_preference,
- base::ThreadTaskRunnerHandle::Get());
+ std::move(channel), gpu::kNullSurfaceHandle, share_buffer,
+ gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL, attrib_helper,
+ GURL::EmptyGURL(), base::ThreadTaskRunnerHandle::Get());
if (!command_buffer_)
return false;
@@ -263,10 +284,6 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context,
if (command_buffer_id)
*command_buffer_id = command_buffer_->GetCommandBufferID();
- mailbox_ = gpu::Mailbox::Generate();
- if (!command_buffer_->ProduceFrontBuffer(mailbox_))
- return false;
-
return true;
}
@@ -344,4 +361,14 @@ void PPB_Graphics3D_Impl::SendContextLost() {
ppp_graphics_3d->Graphics3DContextLost(this_pp_instance);
}
+gpu::Mailbox PPB_Graphics3D_Impl::GenerateMailbox() {
+ if (!mailboxes_to_reuse_.empty()) {
+ gpu::Mailbox mailbox = mailboxes_to_reuse_.back();
+ mailboxes_to_reuse_.pop_back();
+ return mailbox;
+ }
+
+ return gpu::Mailbox::Generate();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
index 8216f631b7e..abafd2c4b14 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -47,6 +47,10 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
gpu::CommandBuffer::State WaitForGetOffsetInRange(int32_t start,
int32_t end) override;
void EnsureWorkVisible() override;
+ void TakeFrontBuffer() override;
+ void ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+ const gpu::SyncToken& sync_token,
+ bool is_lost);
// Binds/unbinds the graphics of this context with the associated instance.
// Returns true if binding/unbinding is successful.
@@ -59,11 +63,6 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
// These messages are used to send Flush callbacks to the plugin.
void ViewInitiatedPaint();
- void GetBackingMailbox(gpu::Mailbox* mailbox, gpu::SyncToken* sync_token) {
- *mailbox = mailbox_;
- *sync_token = sync_token_;
- }
-
gpu::CommandBufferProxyImpl* GetCommandBufferProxy();
protected:
@@ -92,6 +91,16 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
// Notifications sent to plugin.
void SendContextLost();
+ // Reuses a mailbox if one is available, otherwise makes a new one.
+ gpu::Mailbox GenerateMailbox();
+
+ // A front buffer that was recently taken from the command buffer. This should
+ // be immediately consumed by DoSwapBuffers().
+ gpu::Mailbox taken_front_buffer_;
+
+ // Mailboxes that are no longer in use.
+ std::vector<gpu::Mailbox> mailboxes_to_reuse_;
+
// True if context is bound to instance.
bool bound_to_instance_;
// True when waiting for compositor to commit our backing texture.
@@ -101,8 +110,6 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
bool lost_context_ = false;
#endif
- gpu::Mailbox mailbox_;
- gpu::SyncToken sync_token_;
bool has_alpha_;
std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
index 0f31ea09a21..360f5d4e3e5 100644
--- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc
@@ -239,6 +239,7 @@ void PPB_VideoDecoder_Impl::Destroy() {
void PPB_VideoDecoder_Impl::ProvidePictureBuffers(
uint32_t requested_num_of_buffers,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) {
diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h
index c0597a23211..635a5ce47e4 100644
--- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h
+++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h
@@ -45,6 +45,7 @@ class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared,
// media::VideoDecodeAccelerator::Client implementation.
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
+ media::VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
diff --git a/chromium/content/renderer/pepper/video_encoder_shim.cc b/chromium/content/renderer/pepper/video_encoder_shim.cc
index ab466b395da..0887863363b 100644
--- a/chromium/content/renderer/pepper/video_encoder_shim.cc
+++ b/chromium/content/renderer/pepper/video_encoder_shim.cc
@@ -487,7 +487,8 @@ void VideoEncoderShim::OnBitstreamBufferReady(
bool key_frame) {
DCHECK(RenderThreadImpl::current());
- host_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame);
+ host_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame,
+ frame->timestamp());
}
void VideoEncoderShim::OnNotifyError(
diff --git a/chromium/content/renderer/presentation/presentation_dispatcher.cc b/chromium/content/renderer/presentation/presentation_dispatcher.cc
index bcc2eacc4c4..e9360099ed0 100644
--- a/chromium/content/renderer/presentation/presentation_dispatcher.cc
+++ b/chromium/content/renderer/presentation/presentation_dispatcher.cc
@@ -8,12 +8,13 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "content/public/common/presentation_constants.h"
-#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/presentation/presentation_connection_client.h"
+#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h"
@@ -308,6 +309,10 @@ void PresentationDispatcher::DidCommitProvisionalLoad(
std::swap(message_request_queue_, empty);
}
+void PresentationDispatcher::OnDestruct() {
+ delete this;
+}
+
void PresentationDispatcher::OnScreenAvailabilityUpdated(
const mojo::String& url, bool available) {
const std::string& availability_url = url.get();
@@ -450,8 +455,7 @@ void PresentationDispatcher::ConnectToPresentationServiceIfNeeded() {
if (presentation_service_.get())
return;
- render_frame()->GetServiceRegistry()->ConnectToRemoteService(
- mojo::GetProxy(&presentation_service_));
+ render_frame()->GetRemoteInterfaces()->GetInterface(&presentation_service_);
presentation_service_->SetClient(binding_.CreateInterfacePtrAndBind());
}
diff --git a/chromium/content/renderer/presentation/presentation_dispatcher.h b/chromium/content/renderer/presentation/presentation_dispatcher.h
index 2aee2c0d710..e5fb81427c1 100644
--- a/chromium/content/renderer/presentation/presentation_dispatcher.h
+++ b/chromium/content/renderer/presentation/presentation_dispatcher.h
@@ -94,6 +94,7 @@ class CONTENT_EXPORT PresentationDispatcher
void DidCommitProvisionalLoad(
bool is_new_navigation,
bool is_same_page_navigation) override;
+ void OnDestruct() override;
// blink::mojom::PresentationServiceClient
void OnScreenAvailabilityNotSupported(const mojo::String& url) override;
diff --git a/chromium/content/renderer/push_messaging/push_messaging_dispatcher.cc b/chromium/content/renderer/push_messaging/push_messaging_dispatcher.cc
index b865237174a..471024e90a7 100644
--- a/chromium/content/renderer/push_messaging/push_messaging_dispatcher.cc
+++ b/chromium/content/renderer/push_messaging/push_messaging_dispatcher.cc
@@ -39,6 +39,10 @@ bool PushMessagingDispatcher::OnMessageReceived(const IPC::Message& message) {
return handled;
}
+void PushMessagingDispatcher::OnDestruct() {
+ delete this;
+}
+
void PushMessagingDispatcher::subscribe(
blink::WebServiceWorkerRegistration* service_worker_registration,
const blink::WebPushSubscriptionOptions& options,
diff --git a/chromium/content/renderer/push_messaging/push_messaging_dispatcher.h b/chromium/content/renderer/push_messaging/push_messaging_dispatcher.h
index 5dcbf8bf943..5fb894f6b5c 100644
--- a/chromium/content/renderer/push_messaging/push_messaging_dispatcher.h
+++ b/chromium/content/renderer/push_messaging/push_messaging_dispatcher.h
@@ -39,8 +39,9 @@ class PushMessagingDispatcher : public RenderFrameObserver,
~PushMessagingDispatcher() override;
private:
- // RenderFrame::Observer implementation.
+ // RenderFrameObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
// WebPushClient implementation.
void subscribe(
diff --git a/chromium/content/renderer/raster_worker_pool_unittest.cc b/chromium/content/renderer/raster_worker_pool_unittest.cc
deleted file mode 100644
index 73f83dcdf6a..00000000000
--- a/chromium/content/renderer/raster_worker_pool_unittest.cc
+++ /dev/null
@@ -1,120 +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 "base/test/sequenced_task_runner_test_template.h"
-#include "base/test/task_runner_test_template.h"
-#include "base/threading/simple_thread.h"
-#include "cc/test/task_graph_runner_test_template.h"
-#include "content/renderer/raster_worker_pool.h"
-
-namespace base {
-namespace {
-
-// Number of threads spawned in tests.
-const int kNumThreads = 4;
-
-class RasterWorkerPoolTestDelegate {
- public:
- RasterWorkerPoolTestDelegate()
- : raster_worker_pool_(new content::RasterWorkerPool()) {}
-
- void StartTaskRunner() {
- raster_worker_pool_->Start(kNumThreads);
- }
-
- scoped_refptr<content::RasterWorkerPool> GetTaskRunner() {
- return raster_worker_pool_;
- }
-
- void StopTaskRunner() { raster_worker_pool_->FlushForTesting(); }
-
- ~RasterWorkerPoolTestDelegate() { raster_worker_pool_->Shutdown(); }
-
- private:
- scoped_refptr<content::RasterWorkerPool> raster_worker_pool_;
-};
-
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool,
- TaskRunnerTest,
- RasterWorkerPoolTestDelegate);
-
-class RasterWorkerPoolSequencedTestDelegate {
- public:
- RasterWorkerPoolSequencedTestDelegate()
- : raster_worker_pool_(new content::RasterWorkerPool()) {}
-
- void StartTaskRunner() {
- raster_worker_pool_->Start(kNumThreads);
- }
-
- scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
- return raster_worker_pool_->CreateSequencedTaskRunner();
- }
-
- void StopTaskRunner() { raster_worker_pool_->FlushForTesting(); }
-
- ~RasterWorkerPoolSequencedTestDelegate() { raster_worker_pool_->Shutdown(); }
-
- private:
- scoped_refptr<content::RasterWorkerPool> raster_worker_pool_;
-};
-
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool,
- SequencedTaskRunnerTest,
- RasterWorkerPoolSequencedTestDelegate);
-
-} // namespace
-} // namespace base
-
-namespace cc {
-namespace {
-
-template <int NumThreads>
-class RasterWorkerPoolTaskGraphRunnerTestDelegate {
- public:
- RasterWorkerPoolTaskGraphRunnerTestDelegate()
- : raster_worker_pool_(new content::RasterWorkerPool()) {}
-
- void StartTaskGraphRunner() {
- raster_worker_pool_->Start(NumThreads);
- }
-
- cc::TaskGraphRunner* GetTaskGraphRunner() {
- return raster_worker_pool_->GetTaskGraphRunner();
- }
-
- void StopTaskGraphRunner() { raster_worker_pool_->FlushForTesting(); }
-
- ~RasterWorkerPoolTaskGraphRunnerTestDelegate() {
- raster_worker_pool_->Shutdown();
- }
-
- private:
- scoped_refptr<content::RasterWorkerPool> raster_worker_pool_;
-};
-
-// Multithreaded tests.
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool_1_Threads,
- TaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<1>);
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool_2_Threads,
- TaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<2>);
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool_3_Threads,
- TaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<3>);
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool_4_Threads,
- TaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<4>);
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool_5_Threads,
- TaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<5>);
-
-// Single threaded tests.
-INSTANTIATE_TYPED_TEST_CASE_P(RasterWorkerPool,
- SingleThreadTaskGraphRunnerTest,
- RasterWorkerPoolTaskGraphRunnerTestDelegate<1>);
-
-} // namespace
-} // namespace cc
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index 8d049b23fc0..faa00b78063 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -50,6 +50,7 @@
#include "content/child/weburlresponse_extradata_impl.h"
#include "content/common/accessibility_messages.h"
#include "content/common/clipboard_messages.h"
+#include "content/common/content_constants_internal.h"
#include "content/common/content_security_policy_header.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_replication_state.h"
@@ -69,8 +70,10 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
+#include "content/public/common/file_chooser_file_info.h"
+#include "content/public/common/file_chooser_params.h"
#include "content/public/common/isolated_world_ids.h"
-#include "content/public/common/mhtml_generation_params.h"
+#include "content/public/common/mojo_shell_connection.h"
#include "content/public/common/page_state.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/url_constants.h"
@@ -82,7 +85,7 @@
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/renderer_ppapi_host.h"
-#include "content/renderer/accessibility/renderer_accessibility.h"
+#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/bluetooth/web_bluetooth_impl.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
@@ -110,10 +113,11 @@
#include "content/renderer/media/user_media_client_impl.h"
#include "content/renderer/media/web_media_element_source_utils.h"
#include "content/renderer/media/webmediaplayer_ms.h"
-#include "content/renderer/mojo/service_registry_js_wrapper.h"
+#include "content/renderer/mojo/interface_provider_js_wrapper.h"
#include "content/renderer/mojo_bindings_controller.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/notification_permission_dispatcher.h"
+#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/presentation/presentation_dispatcher.h"
#include "content/renderer/push_messaging/push_messaging_dispatcher.h"
@@ -145,18 +149,22 @@
#include "media/blink/webencryptedmediaclient_impl.h"
#include "media/blink/webmediaplayer_impl.h"
#include "media/renderers/gpu_video_accelerator_factories.h"
-#include "mojo/common/url_type_converters.h"
#include "mojo/edk/js/core.h"
#include "mojo/edk/js/support.h"
#include "net/base/data_url.h"
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/http/http_util.h"
+#include "services/shell/public/cpp/interface_provider.h"
+#include "services/shell/public/cpp/interface_registry.h"
+#include "storage/common/data_element.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
+#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
#include "third_party/WebKit/public/platform/WebString.h"
@@ -169,6 +177,7 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebFrameSerializer.h"
+#include "third_party/WebKit/public/web/WebFrameSerializerCacheControlPolicy.h"
#include "third_party/WebKit/public/web/WebFrameWidget.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -231,17 +240,17 @@
#endif
#if defined(ENABLE_MOJO_CDM)
-#include "media/mojo/services/mojo_cdm_factory.h" // nogncheck
+#include "media/mojo/clients/mojo_cdm_factory.h" // nogncheck
#endif
#if defined(ENABLE_MOJO_RENDERER)
-#include "media/mojo/services/mojo_renderer_factory.h" // nogncheck
+#include "media/mojo/clients/mojo_renderer_factory.h" // nogncheck
#else
#include "media/renderers/default_renderer_factory.h"
#endif
#if defined(ENABLE_MOJO_AUDIO_DECODER) || defined(ENABLE_MOJO_VIDEO_DECODER)
-#include "media/mojo/services/mojo_decoder_factory.h" // nogncheck
+#include "media/mojo/clients/mojo_decoder_factory.h" // nogncheck
#endif
using blink::WebCachePolicy;
@@ -273,6 +282,7 @@ using blink::WebNavigationType;
using blink::WebNode;
using blink::WebPluginDocument;
using blink::WebPluginParams;
+using blink::WebPoint;
using blink::WebPopupMenuInfo;
using blink::WebRange;
using blink::WebRect;
@@ -301,6 +311,10 @@ using blink::WebFloatPoint;
using blink::WebFloatRect;
#endif
+#define STATIC_ASSERT_ENUM(a, b) \
+ static_assert(static_cast<int>(a) == static_cast<int>(b), \
+ "mismatching enums: " #a)
+
namespace content {
namespace {
@@ -522,10 +536,11 @@ WebURLRequest CreateURLRequestForNavigation(
}
request.setHTTPMethod(WebString::fromUTF8(common_params.method));
+ request.setLoFiState(
+ static_cast<WebURLRequest::LoFiState>(common_params.lofi_state));
RequestExtraData* extra_data = new RequestExtraData();
extra_data->set_stream_override(std::move(stream_override));
- extra_data->set_lofi_state(common_params.lofi_state);
request.setExtraData(extra_data);
// Set the ui timestamp for this navigation. Currently the timestamp here is
@@ -597,8 +612,9 @@ CommonNavigationParams MakeCommonNavigationParams(
return CommonNavigationParams(
request->url(), referrer, extra_data->transition_type(),
FrameMsg_Navigate_Type::NORMAL, true, should_replace_current_entry,
- ui_timestamp, report_type, GURL(), GURL(), extra_data->lofi_state(),
- base::TimeTicks::Now(), request->httpMethod().latin1());
+ ui_timestamp, report_type, GURL(), GURL(),
+ static_cast<LoFiState>(request->getLoFiState()),base::TimeTicks::Now(),
+ request->httpMethod().latin1(), GetRequestBodyForWebURLRequest(*request));
}
media::Context3D GetSharedMainThreadContext3D(
@@ -648,7 +664,7 @@ RenderFrameImpl::CreateRenderFrameImplFunction g_create_render_frame_impl =
nullptr;
void OnGotInstanceID(shell::mojom::ConnectResult result,
- const std::string& user_id,
+ mojo::String user_id,
uint32_t instance_id) {}
WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
@@ -739,6 +755,12 @@ class MHTMLPartsGenerationDelegate
return WebString::fromUTF8(content_id);
}
+ blink::WebFrameSerializerCacheControlPolicy cacheControlPolicy() override {
+ return params_.mhtml_cache_control_policy;
+ }
+
+ bool useBinaryEncoding() override { return params_.mhtml_binary_encoding; }
+
private:
const FrameMsg_SerializeAsMHTML_Params& params_;
std::set<std::string>* digests_of_uris_of_serialized_resources_;
@@ -793,6 +815,10 @@ bool IsContentWithCertificateErrorsRelevantToUI(
ssl_status.connection_status);
}
+bool IsHttpPost(const blink::WebURLRequest& request) {
+ return request.httpMethod().utf8() == "POST";
+}
+
#if defined(OS_ANDROID)
// Returns true if WMPI should be used for playback, false otherwise.
//
@@ -840,6 +866,14 @@ bool UseMojoCdm() {
} // namespace
+struct RenderFrameImpl::PendingFileChooser {
+ PendingFileChooser(const FileChooserParams& p,
+ blink::WebFileChooserCompletion* c)
+ : params(p), completion(c) {}
+ FileChooserParams params;
+ blink::WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
+};
+
// static
RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view,
int32_t routing_id) {
@@ -887,9 +921,6 @@ RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
render_view->webview()->setMainFrame(web_frame);
render_frame->render_widget_ = RenderWidget::CreateForFrame(
widget_routing_id, hidden, screen_info, compositor_deps, web_frame);
- // TODO(kenrb): Observing shouldn't be necessary when we sort out
- // WasShown and WasHidden, separating page-level visibility from
- // frame-level visibility.
// TODO(avi): This DCHECK is to track cleanup for https://crbug.com/545684
DCHECK_EQ(render_view->GetWidget(), render_frame->render_widget_)
<< "Main frame is no longer reusing the RenderView as its widget! "
@@ -952,8 +983,7 @@ void RenderFrameImpl::CreateFrame(
render_frame->InitializeBlameContext(nullptr);
render_frame->proxy_routing_id_ = proxy_routing_id;
web_frame = blink::WebLocalFrame::createProvisional(
- render_frame, proxy->web_frame(), replicated_state.sandbox_flags,
- frame_owner_properties);
+ render_frame, proxy->web_frame(), replicated_state.sandbox_flags);
}
render_frame->BindToWebFrame(web_frame);
CHECK(parent_routing_id != MSG_ROUTING_NONE || !web_frame->parent());
@@ -967,12 +997,8 @@ void RenderFrameImpl::CreateFrame(
// TODO(avi): The main frame re-uses the RenderViewImpl as its widget, so
// avoid double-registering the frame as an observer.
// https://crbug.com/545684
- if (web_frame->parent()) {
- // TODO(kenrb): Observing shouldn't be necessary when we sort out
- // WasShown and WasHidden, separating page-level visibility from
- // frame-level visibility.
+ if (web_frame->parent())
render_frame->render_widget_->RegisterRenderFrame(render_frame);
- }
}
render_frame->Initialize();
@@ -1037,7 +1063,6 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
in_frame_tree_(false),
render_view_(params.render_view->AsWeakPtr()),
routing_id_(params.routing_id),
- is_detaching_(false),
proxy_routing_id_(MSG_ROUTING_NONE),
#if defined(ENABLE_PLUGINS)
plugin_power_saver_helper_(nullptr),
@@ -1064,11 +1089,10 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
devtools_agent_(nullptr),
push_messaging_dispatcher_(NULL),
presentation_dispatcher_(NULL),
- blink_service_registry_(service_registry_.GetWeakPtr()),
screen_orientation_dispatcher_(NULL),
manifest_manager_(NULL),
accessibility_mode_(AccessibilityModeOff),
- renderer_accessibility_(NULL),
+ render_accessibility_(NULL),
media_player_delegate_(NULL),
is_using_lofi_(false),
effective_connection_type_(
@@ -1080,7 +1104,19 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
focused_pepper_plugin_(nullptr),
pepper_last_mouse_event_target_(nullptr),
#endif
+ frame_binding_(this),
weak_factory_(this) {
+ // We don't have a shell::Connection at this point, so use nullptr.
+ // TODO(beng): We should fix this, so we can apply policy about which
+ // interfaces get exposed.
+ interface_registry_.reset(new shell::InterfaceRegistry(nullptr));
+ shell::mojom::InterfaceProviderPtr remote_interfaces;
+ pending_remote_interface_provider_request_ = GetProxy(&remote_interfaces);
+ remote_interfaces_.reset(new shell::InterfaceProvider);
+ remote_interfaces_->Bind(std::move(remote_interfaces));
+ blink_service_registry_.reset(new BlinkServiceRegistryImpl(
+ remote_interfaces_->GetWeakPtr()));
+
std::pair<RoutingIDFrameMap::iterator, bool> result =
g_routing_id_frame_map.Get().insert(std::make_pair(routing_id_, this));
CHECK(result.second) << "Inserting a duplicate item.";
@@ -1104,6 +1140,15 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
}
RenderFrameImpl::~RenderFrameImpl() {
+ // If file chooser is still waiting for answer, dispatch empty answer.
+ while (!file_chooser_completions_.empty()) {
+ if (file_chooser_completions_.front()->completion) {
+ file_chooser_completions_.front()->completion->didChooseFile(
+ WebVector<WebString>());
+ }
+ file_chooser_completions_.pop_front();
+ }
+
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone());
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct());
@@ -1176,7 +1221,7 @@ void RenderFrameImpl::Initialize() {
devtools_agent_ = new DevToolsAgent(this);
}
- RegisterMojoServices();
+ RegisterMojoInterfaces();
// We delay calling this until we have the WebFrame so that any observer or
// embedder can call GetWebFrame on any RenderFrame.
@@ -1194,7 +1239,7 @@ void RenderFrameImpl::Initialize() {
void RenderFrameImpl::InitializeBlameContext(RenderFrameImpl* parent_frame) {
DCHECK(!blame_context_);
- blame_context_ = new FrameBlameContext(this, parent_frame);
+ blame_context_ = base::WrapUnique(new FrameBlameContext(this, parent_frame));
blame_context_->Initialize();
}
@@ -1392,15 +1437,10 @@ MediaStreamDispatcher* RenderFrameImpl::GetMediaStreamDispatcher() {
}
bool RenderFrameImpl::Send(IPC::Message* message) {
- if (is_detaching_) {
- delete message;
- return false;
- }
-
return RenderThread::Get()->Send(message);
}
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(USE_EXTERNAL_POPUP_MENU)
void RenderFrameImpl::DidHideExternalPopupMenu() {
// We need to clear external_popup_menu_ as soon as ExternalPopupMenu::close
// is called. Otherwise, createExternalPopupMenu() for new popup will fail.
@@ -1447,6 +1487,9 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed)
IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction,
OnCustomContextMenuAction)
+#if defined(ENABLE_PLUGINS)
+ IPC_MESSAGE_HANDLER(FrameMsg_SetPepperVolume, OnSetPepperVolume)
+#endif //defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo)
IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo)
IPC_MESSAGE_HANDLER(InputMsg_Cut, OnCut)
@@ -1463,6 +1506,8 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
OnMoveRangeSelectionExtent)
IPC_MESSAGE_HANDLER(InputMsg_Replace, OnReplace)
IPC_MESSAGE_HANDLER(InputMsg_ReplaceMisspelling, OnReplaceMisspelling)
+ IPC_MESSAGE_HANDLER(FrameMsg_CopyImageAt, OnCopyImageAt)
+ IPC_MESSAGE_HANDLER(FrameMsg_SaveImageAt, OnSaveImageAt)
IPC_MESSAGE_HANDLER(InputMsg_ExtendSelectionAndDelete,
OnExtendSelectionAndDelete)
IPC_MESSAGE_HANDLER(InputMsg_SetCompositionFromExistingText,
@@ -1506,17 +1551,29 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
OnGetSerializedHtmlWithLocalLinks)
IPC_MESSAGE_HANDLER(FrameMsg_SerializeAsMHTML, OnSerializeAsMHTML)
IPC_MESSAGE_HANDLER(FrameMsg_Find, OnFind)
+ IPC_MESSAGE_HANDLER(FrameMsg_ClearActiveFindMatch, OnClearActiveFindMatch)
IPC_MESSAGE_HANDLER(FrameMsg_StopFinding, OnStopFinding)
IPC_MESSAGE_HANDLER(FrameMsg_EnableViewSourceMode, OnEnableViewSourceMode)
IPC_MESSAGE_HANDLER(FrameMsg_SuppressFurtherDialogs,
OnSuppressFurtherDialogs)
+ IPC_MESSAGE_HANDLER(FrameMsg_RunFileChooserResponse, OnFileChooserResponse)
#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(InputMsg_ActivateNearestFindResult,
+ IPC_MESSAGE_HANDLER(FrameMsg_ActivateNearestFindResult,
OnActivateNearestFindResult)
+ IPC_MESSAGE_HANDLER(FrameMsg_GetNearestFindResult,
+ OnGetNearestFindResult)
IPC_MESSAGE_HANDLER(FrameMsg_FindMatchRects, OnFindMatchRects)
- IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
-#elif defined(OS_MACOSX)
+#endif
+
+#if defined(USE_EXTERNAL_POPUP_MENU)
+#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
+#else
+ IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
+#endif
+#endif
+
+#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(InputMsg_CopyToFindPboard, OnCopyToFindPboard)
#endif
IPC_END_MESSAGE_MAP()
@@ -1552,11 +1609,12 @@ void RenderFrameImpl::OnNavigate(
std::unique_ptr<StreamOverrideParameters>());
}
-void RenderFrameImpl::BindServiceRegistry(
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services) {
- service_registry_.Bind(std::move(services));
- service_registry_.BindRemoteServiceProvider(std::move(exposed_services));
+void RenderFrameImpl::Bind(mojom::FrameRequest request,
+ mojom::FrameHostPtr host) {
+ frame_binding_.Bind(std::move(request));
+ frame_host_ = std::move(host);
+ frame_host_->GetInterfaceProvider(
+ std::move(pending_remote_interface_provider_request_));
}
ManifestManager* RenderFrameImpl::manifest_manager() {
@@ -1568,7 +1626,7 @@ void RenderFrameImpl::SetPendingNavigationParams(
pending_navigation_params_ = std::move(navigation_params);
}
-void RenderFrameImpl::OnBeforeUnload() {
+void RenderFrameImpl::OnBeforeUnload(bool is_reload) {
TRACE_EVENT1("navigation", "RenderFrameImpl::OnBeforeUnload",
"id", routing_id_);
// TODO(creis): Right now, this is only called on the main frame. Make the
@@ -1577,11 +1635,10 @@ void RenderFrameImpl::OnBeforeUnload() {
CHECK(!frame_->parent());
base::TimeTicks before_unload_start_time = base::TimeTicks::Now();
- bool proceed = frame_->dispatchBeforeUnloadEvent();
+ bool proceed = frame_->dispatchBeforeUnloadEvent(is_reload);
base::TimeTicks before_unload_end_time = base::TimeTicks::Now();
- Send(new FrameHostMsg_BeforeUnload_ACK(routing_id_, proceed,
- before_unload_start_time,
- before_unload_end_time));
+ Send(new FrameHostMsg_BeforeUnload_ACK(
+ routing_id_, proceed, before_unload_start_time, before_unload_end_time));
}
void RenderFrameImpl::OnSwapOut(
@@ -1626,14 +1683,6 @@ void RenderFrameImpl::OnSwapOut(
if (!is_main_frame_)
proxy->web_frame()->initializeFromFrame(frame_);
- // Let WebKit know that this view is hidden so it can drop resources and
- // stop compositing.
- // TODO(creis): Support this for subframes as well.
- if (is_main_frame_) {
- render_view_->webview()->setVisibilityState(
- blink::WebPageVisibilityStateHidden, false);
- }
-
RenderViewImpl* render_view = render_view_.get();
bool is_main_frame = is_main_frame_;
int routing_id = GetRoutingID();
@@ -1851,6 +1900,14 @@ void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) {
frame_->replaceMisspelledRange(text);
}
+void RenderFrameImpl::OnCopyImageAt(int x, int y) {
+ frame_->copyImageAt(WebPoint(x, y));
+}
+
+void RenderFrameImpl::OnSaveImageAt(int x, int y) {
+ frame_->saveImageAt(WebPoint(x, y));
+}
+
void RenderFrameImpl::OnCSSInsertRequest(const std::string& css) {
frame_->document().insertStyleSheet(WebString::fromUTF8(css));
}
@@ -2031,25 +2088,25 @@ void RenderFrameImpl::OnSetAccessibilityMode(AccessibilityMode new_mode) {
if (accessibility_mode_ == new_mode)
return;
accessibility_mode_ = new_mode;
- if (renderer_accessibility_) {
+ if (render_accessibility_) {
// Note: this isn't called automatically by the destructor because
// there'd be no point in calling it in frame teardown, only if there's
// an accessibility mode change but the frame is persisting.
- renderer_accessibility_->DisableAccessibility();
+ render_accessibility_->DisableAccessibility();
- delete renderer_accessibility_;
- renderer_accessibility_ = NULL;
+ delete render_accessibility_;
+ render_accessibility_ = NULL;
}
if (accessibility_mode_ == AccessibilityModeOff)
return;
if (accessibility_mode_ & AccessibilityModeFlagFullTree)
- renderer_accessibility_ = new RendererAccessibility(this);
+ render_accessibility_ = new RenderAccessibilityImpl(this);
}
void RenderFrameImpl::OnSnapshotAccessibilityTree(int callback_id) {
AXContentTreeUpdate response;
- RendererAccessibility::SnapshotAccessibilityTree(this, &response);
+ RenderAccessibilityImpl::SnapshotAccessibilityTree(this, &response);
Send(new AccessibilityHostMsg_SnapshotResponse(
routing_id_, callback_id, response));
}
@@ -2214,6 +2271,31 @@ bool RenderFrameImpl::RunJavaScriptMessage(JavaScriptMessageType type,
return success;
}
+bool RenderFrameImpl::ScheduleFileChooser(
+ const FileChooserParams& params,
+ blink::WebFileChooserCompletion* completion) {
+ static const size_t kMaximumPendingFileChooseRequests = 4;
+ if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
+ // This sanity check prevents too many file choose requests from getting
+ // queued which could DoS the user. Getting these is most likely a
+ // programming error (there are many ways to DoS the user so it's not
+ // considered a "real" security check), either in JS requesting many file
+ // choosers to pop up, or in a plugin.
+ //
+ // TODO(brettw): We might possibly want to require a user gesture to open
+ // a file picker, which will address this issue in a better way.
+ return false;
+ }
+
+ file_chooser_completions_.push_back(
+ base::WrapUnique(new PendingFileChooser(params, completion)));
+ if (file_chooser_completions_.size() == 1) {
+ // Actually show the browse dialog when this is the first request.
+ Send(new FrameHostMsg_RunFileChooser(routing_id_, params));
+ }
+ return true;
+}
+
void RenderFrameImpl::LoadNavigationErrorPage(
const WebURLRequest& failed_request,
const WebURLError& error,
@@ -2258,6 +2340,10 @@ RenderView* RenderFrameImpl::GetRenderView() {
return render_view_.get();
}
+RenderAccessibility* RenderFrameImpl::GetRenderAccessibility() {
+ return render_accessibility_;
+}
+
int RenderFrameImpl::GetRoutingID() {
return routing_id_;
}
@@ -2334,8 +2420,12 @@ void RenderFrameImpl::ExecuteJavaScript(const base::string16& javascript) {
OnJavaScriptExecuteRequest(javascript, 0, false);
}
-ServiceRegistry* RenderFrameImpl::GetServiceRegistry() {
- return &service_registry_;
+shell::InterfaceRegistry* RenderFrameImpl::GetInterfaceRegistry() {
+ return interface_registry_.get();
+}
+
+shell::InterfaceProvider* RenderFrameImpl::GetRemoteInterfaces() {
+ return remote_interfaces_.get();
}
#if defined(ENABLE_PLUGINS)
@@ -2398,13 +2488,14 @@ void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
registry->AddBuiltinModule(isolate, mojo::edk::js::Support::kModuleName,
mojo::edk::js::Support::GetModule(isolate));
registry->AddBuiltinModule(
- isolate, ServiceRegistryJsWrapper::kPerFrameModuleName,
- ServiceRegistryJsWrapper::Create(isolate, context, &service_registry_)
+ isolate, InterfaceProviderJsWrapper::kPerFrameModuleName,
+ InterfaceProviderJsWrapper::Create(
+ isolate, context, remote_interfaces_.get())
.ToV8());
registry->AddBuiltinModule(
- isolate, ServiceRegistryJsWrapper::kPerProcessModuleName,
- ServiceRegistryJsWrapper::Create(
- isolate, context, RenderThread::Get()->GetServiceRegistry())
+ isolate, InterfaceProviderJsWrapper::kPerProcessModuleName,
+ InterfaceProviderJsWrapper::Create(
+ isolate, context, RenderThread::Get()->GetRemoteInterfaces())
.ToV8());
}
@@ -2439,6 +2530,13 @@ bool RenderFrameImpl::IsPasting() const {
return is_pasting_;
}
+// mojom::Frame implementation -------------------------------------------------
+
+void RenderFrameImpl::GetInterfaceProvider(
+ shell::mojom::InterfaceProviderRequest request) {
+ interface_registry_->Bind(std::move(request));
+}
+
// blink::WebFrameClient implementation ----------------------------------------
blink::WebPlugin* RenderFrameImpl::createPlugin(
@@ -2520,7 +2618,9 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
&GetSharedMainThreadContext3D,
RenderThreadImpl::current()->SharedMainThreadContextProvider());
- scoped_refptr<media::MediaLog> media_log(new RenderMediaLog());
+ scoped_refptr<media::MediaLog> media_log(new RenderMediaLog(
+ blink::WebStringToGURL(frame_->getSecurityOrigin().toString())));
+
#if defined(OS_ANDROID)
if (UseWebMediaPlayerImpl(url) && !media_surface_manager_)
media_surface_manager_ = new RendererSurfaceViewManager(this);
@@ -2558,8 +2658,7 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
media_renderer_factory.reset(new media::DefaultRendererFactory(
media_log, GetDecoderFactory(),
base::Bind(&RenderThreadImpl::GetGpuFactories,
- base::Unretained(render_thread)),
- *render_thread->GetAudioHardwareConfig()));
+ base::Unretained(render_thread))));
}
#endif // defined(ENABLE_MOJO_RENDERER)
@@ -2607,7 +2706,7 @@ RenderFrameImpl::createWorkerContentSettingsClientProxy() {
WebExternalPopupMenu* RenderFrameImpl::createExternalPopupMenu(
const WebPopupMenuInfo& popup_menu_info,
WebExternalPopupMenuClient* popup_menu_client) {
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(USE_EXTERNAL_POPUP_MENU)
// An IPC message is sent to the browser to build and display the actual
// popup. The user could have time to click a different select by the time
// the popup is shown. In that case external_popup_menu_ is non NULL.
@@ -2635,7 +2734,7 @@ blink::WebCookieJar* RenderFrameImpl::cookieJar() {
blink::BlameContext* RenderFrameImpl::frameBlameContext() {
DCHECK(blame_context_);
- return blame_context_;
+ return blame_context_.get();
}
blink::WebServiceWorkerProvider*
@@ -2658,6 +2757,9 @@ RenderFrameImpl::createServiceWorkerProvider() {
}
void RenderFrameImpl::didAccessInitialDocument() {
+ // NOTE: Do not call back into JavaScript here, since this call is made from a
+ // V8 security check.
+
// If the request hasn't yet committed, notify the browser process that it is
// no longer safe to show the pending URL of the main frame, since a URL spoof
// is now possible. (If the request has committed, the browser already knows.)
@@ -2738,7 +2840,6 @@ void RenderFrameImpl::frameDetached(blink::WebFrame* frame, DetachType type) {
// NOTE: This function is called on the frame that is being detached and not
// the parent frame. This is different from createChildFrame() which is
// called on the parent frame.
- CHECK(!is_detaching_);
DCHECK_EQ(frame_, frame);
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameDetached());
@@ -2750,10 +2851,6 @@ void RenderFrameImpl::frameDetached(blink::WebFrame* frame, DetachType type) {
if (!in_browser_initiated_detach_ && type == DetachType::Remove)
Send(new FrameHostMsg_Detach(routing_id_));
- // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
- // sent before setting |is_detaching_| to true.
- is_detaching_ = true;
-
// Clean up the associated RenderWidget for the frame, if there is one.
if (render_widget_) {
render_widget_->UnregisterRenderFrame(this);
@@ -2818,8 +2915,9 @@ void RenderFrameImpl::didChangeName(const blink::WebString& name,
}
}
-void RenderFrameImpl::didEnforceStrictMixedContentChecking() {
- Send(new FrameHostMsg_EnforceStrictMixedContentChecking(routing_id_));
+void RenderFrameImpl::didEnforceInsecureRequestPolicy(
+ blink::WebInsecureRequestPolicy policy) {
+ Send(new FrameHostMsg_EnforceInsecureRequestPolicy(routing_id_, policy));
}
void RenderFrameImpl::didUpdateToUniqueOrigin(
@@ -2915,13 +3013,13 @@ void RenderFrameImpl::loadURLExternally(const blink::WebURLRequest& request,
bool should_replace_current_entry) {
Referrer referrer(RenderViewImpl::GetReferrerFromRequest(frame_, request));
if (policy == blink::WebNavigationPolicyDownload) {
- render_view_->Send(new ViewHostMsg_DownloadUrl(render_view_->GetRoutingID(),
- GetRoutingID(),
- request.url(), referrer,
- suggested_name));
+ Send(new FrameHostMsg_DownloadUrl(render_view_->GetRoutingID(),
+ GetRoutingID(), request.url(), referrer,
+ suggested_name));
} else {
- OpenURL(request.url(), referrer, policy, should_replace_current_entry,
- false);
+ OpenURL(request.url(), IsHttpPost(request),
+ GetRequestBodyForWebURLRequest(request), referrer, policy,
+ should_replace_current_entry, false);
}
}
@@ -3072,9 +3170,8 @@ void RenderFrameImpl::didCreateDataSource(blink::WebLocalFrame* frame,
ServiceWorkerNetworkProvider::AttachToDocumentState(
DocumentState::FromDataSource(datasource),
- ServiceWorkerNetworkProvider::CreateForNavigation(
- routing_id_, navigation_state->request_params(), frame,
- content_initiated));
+ ServiceWorkerNetworkProvider::CreateForNavigation(routing_id_, frame,
+ content_initiated));
}
void RenderFrameImpl::didStartProvisionalLoad(blink::WebLocalFrame* frame,
@@ -3740,6 +3837,37 @@ bool RenderFrameImpl::runModalBeforeUnloadDialog(bool is_reload) {
return success;
}
+bool RenderFrameImpl::runFileChooser(
+ const blink::WebFileChooserParams& params,
+ blink::WebFileChooserCompletion* chooser_completion) {
+ // Do not open the file dialog in a hidden RenderFrame.
+ if (IsHidden())
+ return false;
+
+ FileChooserParams ipc_params;
+ if (params.directory)
+ ipc_params.mode = FileChooserParams::UploadFolder;
+ else if (params.multiSelect)
+ ipc_params.mode = FileChooserParams::OpenMultiple;
+ else if (params.saveAs)
+ ipc_params.mode = FileChooserParams::Save;
+ else
+ ipc_params.mode = FileChooserParams::Open;
+ ipc_params.title = params.title;
+ ipc_params.default_file_name =
+ blink::WebStringToFilePath(params.initialValue).BaseName();
+ ipc_params.accept_types.reserve(params.acceptTypes.size());
+ for (const auto& type : params.acceptTypes)
+ ipc_params.accept_types.push_back(type);
+ ipc_params.need_local_path = params.needLocalPath;
+#if defined(OS_ANDROID)
+ ipc_params.capture = params.useMediaCapture;
+#endif
+ ipc_params.requestor = params.requestor;
+
+ return ScheduleFileChooser(ipc_params, chooser_completion);
+}
+
void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) {
ContextMenuParams params = ContextMenuParamsBuilder::Build(data);
blink::WebRect position_in_window(params.x, params.y, 0, 0);
@@ -3773,6 +3901,15 @@ void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) {
Send(new FrameHostMsg_ContextMenu(routing_id_, params));
}
+void RenderFrameImpl::saveImageFromDataURL(const blink::WebString& data_url) {
+ // Note: We should basically send GURL but we use size-limited string instead
+ // in order to send a larger data url to save a image for <canvas> or <img>.
+ if (data_url.length() < kMaxLengthOfDataURLString) {
+ Send(new FrameHostMsg_SaveImageFromDataURL(
+ render_view_->GetRoutingID(), routing_id_, data_url.utf8()));
+ }
+}
+
void RenderFrameImpl::willSendRequest(
blink::WebLocalFrame* frame,
unsigned identifier,
@@ -3787,20 +3924,20 @@ void RenderFrameImpl::willSendRequest(
// requests). This value will be updated during redirects, consistent with
// https://tools.ietf.org/html/draft-west-first-party-cookies-04#section-2.1.1
if (request.firstPartyForCookies().isEmpty()) {
- if (request.getFrameType() == blink::WebURLRequest::FrameTypeTopLevel) {
+ if (request.getFrameType() == blink::WebURLRequest::FrameTypeTopLevel)
request.setFirstPartyForCookies(request.url());
- } else {
- // TODO(nasko): When the top-level frame is remote, there is no document.
- // This is broken and should be fixed to propagate the first party.
- WebFrame* top = frame->top();
- if (top->isWebLocalFrame()) {
- request.setFirstPartyForCookies(
- frame->top()->document().firstPartyForCookies());
- }
- }
+ else
+ request.setFirstPartyForCookies(frame->document().firstPartyForCookies());
+ }
- // If we need to set the first party, then we need to set the request's
- // initiator as well; it will not be updated during redirects.
+ // Set the requestor origin to the same origin as the frame's document if it
+ // hasn't yet been set.
+ //
+ // TODO(mkwst): It would be cleaner to adjust blink::ResourceRequest to
+ // initialize itself with a `nullptr` initiator so that this can be a simple
+ // `isNull()` check.
+ if (request.requestorOrigin().isUnique() &&
+ !frame->document().getSecurityOrigin().isUnique()) {
request.setRequestorOrigin(frame->document().getSecurityOrigin());
}
@@ -3894,15 +4031,18 @@ void RenderFrameImpl::willSendRequest(
provider_id = provider->provider_id();
// Explicitly set the SkipServiceWorker flag here if the renderer process
// hasn't received SetControllerServiceWorker message.
- if (!provider->IsControlledByServiceWorker())
- request.setSkipServiceWorker(true);
+ if (!provider->IsControlledByServiceWorker() &&
+ request.skipServiceWorker() !=
+ blink::WebURLRequest::SkipServiceWorker::All)
+ request.setSkipServiceWorker(
+ blink::WebURLRequest::SkipServiceWorker::Controlling);
}
WebFrame* parent = frame->parent();
int parent_routing_id = parent ? GetRoutingIdForFrameOrProxy(parent) : -1;
RequestExtraData* extra_data = new RequestExtraData();
- extra_data->set_visibility_state(render_view_->visibilityState());
+ extra_data->set_visibility_state(visibilityState());
extra_data->set_custom_user_agent(custom_user_agent);
extra_data->set_requested_with(requested_with);
extra_data->set_render_frame_id(routing_id_);
@@ -3921,14 +4061,21 @@ void RenderFrameImpl::willSendRequest(
navigation_state->start_params().transferred_request_request_id);
extra_data->set_service_worker_provider_id(provider_id);
extra_data->set_stream_override(std::move(stream_override));
- if (request.getLoFiState() != WebURLRequest::LoFiUnspecified)
- extra_data->set_lofi_state(static_cast<LoFiState>(request.getLoFiState()));
- else if (is_main_frame_ && !navigation_state->request_committed())
- extra_data->set_lofi_state(navigation_state->common_params().lofi_state);
- else
- extra_data->set_lofi_state(is_using_lofi_ ? LOFI_ON : LOFI_OFF);
+ WebString error;
+ extra_data->set_initiated_in_secure_context(
+ frame->document().isSecureContext(error));
request.setExtraData(extra_data);
+ if (request.getLoFiState() == WebURLRequest::LoFiUnspecified) {
+ if (is_main_frame_ && !navigation_state->request_committed()) {
+ request.setLoFiState(static_cast<WebURLRequest::LoFiState>(
+ navigation_state->common_params().lofi_state));
+ } else {
+ request.setLoFiState(
+ is_using_lofi_ ? WebURLRequest::LoFiOn : WebURLRequest::LoFiOff);
+ }
+ }
+
// TODO(creis): Update prefetching to work with out-of-process iframes.
WebFrame* top_frame = frame->top();
if (top_frame && top_frame->isWebLocalFrame()) {
@@ -4113,20 +4260,19 @@ void RenderFrameImpl::willInsertBody(blink::WebLocalFrame* frame) {
void RenderFrameImpl::reportFindInPageMatchCount(int request_id,
int count,
bool final_update) {
- int active_match_ordinal = -1; // -1 = don't update active match ordinal
- if (!count)
- active_match_ordinal = 0;
+ // -1 here means don't update the active match ordinal.
+ int active_match_ordinal = count ? -1 : 0;
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, count, gfx::Rect(),
- active_match_ordinal, final_update));
+ SendFindReply(request_id, count, active_match_ordinal, gfx::Rect(),
+ final_update);
}
void RenderFrameImpl::reportFindInPageSelection(
int request_id,
int active_match_ordinal,
const blink::WebRect& selection_rect) {
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, -1, selection_rect,
- active_match_ordinal, false));
+ SendFindReply(request_id, -1 /* match_count */, active_match_ordinal,
+ selection_rect, false /* final_status_update */);
}
void RenderFrameImpl::requestStorageQuota(
@@ -4278,8 +4424,8 @@ void RenderFrameImpl::handleAccessibilityFindInPageResult(
int start_offset,
const blink::WebAXObject& end_object,
int end_offset) {
- if (renderer_accessibility_) {
- renderer_accessibility_->HandleAccessibilityFindInPageResult(
+ if (render_accessibility_) {
+ render_accessibility_->HandleAccessibilityFindInPageResult(
identifier, match_index, start_object, start_offset,
end_object, end_offset);
}
@@ -4300,9 +4446,10 @@ bool RenderFrameImpl::exitFullscreen() {
}
blink::WebPermissionClient* RenderFrameImpl::permissionClient() {
- if (!permission_client_)
- permission_client_.reset(new PermissionDispatcher(GetServiceRegistry()));
-
+ if (!permission_client_) {
+ permission_client_.reset(
+ new PermissionDispatcher(GetRemoteInterfaces()));
+ }
return permission_client_.get();
}
@@ -4338,13 +4485,8 @@ void RenderFrameImpl::unregisterProtocolHandler(const WebString& scheme,
}
blink::WebBluetooth* RenderFrameImpl::bluetooth() {
- // ChildThreadImpl::current() is null in some tests.
- if (!bluetooth_ && ChildThreadImpl::current()) {
- bluetooth_.reset(new WebBluetoothImpl(
- GetServiceRegistry(), ChildThreadImpl::current()->thread_safe_sender(),
- routing_id_));
- }
-
+ if (!bluetooth_.get())
+ bluetooth_.reset(new WebBluetoothImpl(GetRemoteInterfaces()));
return bluetooth_.get();
}
@@ -4381,27 +4523,25 @@ void RenderFrameImpl::WasHidden() {
for (auto* plugin : active_pepper_instances_)
plugin->PageVisibilityChanged(false);
#endif // ENABLE_PLUGINS
+
+ if (GetWebFrame()->frameWidget()) {
+ static_cast<blink::WebFrameWidget*>(GetWebFrame()->frameWidget())
+ ->setVisibilityState(visibilityState());
+ }
}
void RenderFrameImpl::WasShown() {
- // TODO(kenrb): Need to figure out how to do this better. Should
- // VisibilityState remain a page-level concept or move to frames?
- // The semantics of 'Show' might have to change here.
- // TODO(avi): This DCHECK is to track cleanup for https://crbug.com/545684
- DCHECK(!IsMainFrame() || render_widget_.get() == render_view_.get())
- << "The main render frame is no longer reusing the RenderView as its "
- << "RenderWidget!";
- if (render_widget_ && render_widget_->webwidget() &&
- render_view_.get() != render_widget_.get()) {
- static_cast<blink::WebFrameWidget*>(render_widget_->webwidget())->
- setVisibilityState(blink::WebPageVisibilityStateVisible, false);
- }
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, WasShown());
#if defined(ENABLE_PLUGINS)
for (auto* plugin : active_pepper_instances_)
plugin->PageVisibilityChanged(true);
#endif // ENABLE_PLUGINS
+
+ if (GetWebFrame()->frameWidget()) {
+ static_cast<blink::WebFrameWidget*>(GetWebFrame()->frameWidget())
+ ->setVisibilityState(visibilityState());
+ }
}
void RenderFrameImpl::WidgetWillClose() {
@@ -4472,8 +4612,7 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(
// RenderFrameProxies in other processes.
params.origin = frame->document().getSecurityOrigin();
- params.should_enforce_strict_mixed_content_checking =
- frame->shouldEnforceStrictMixedContentChecking();
+ params.insecure_request_policy = frame->getInsecureRequestPolicy();
params.has_potentially_trustworthy_unique_origin =
frame->document().getSecurityOrigin().isUnique() &&
@@ -4665,8 +4804,8 @@ void RenderFrameImpl::didChangeLoadProgress(double load_progress) {
void RenderFrameImpl::HandleWebAccessibilityEvent(
const blink::WebAXObject& obj, blink::WebAXEvent event) {
- if (renderer_accessibility_)
- renderer_accessibility_->HandleWebAccessibilityEvent(obj, event);
+ if (render_accessibility_)
+ render_accessibility_->HandleWebAccessibilityEvent(obj, event);
}
void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
@@ -4674,8 +4813,8 @@ void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
}
void RenderFrameImpl::FocusedNodeChangedForAccessibility(const WebNode& node) {
- if (renderer_accessibility())
- renderer_accessibility()->AccessibilityFocusedNodeChanged(node);
+ if (render_accessibility())
+ render_accessibility()->AccessibilityFocusedNodeChanged(node);
}
// PlzNavigate
@@ -4793,8 +4932,9 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
if (is_content_initiated && IsTopLevelNavigation(frame_) &&
render_view_->renderer_preferences_
.browser_handles_all_top_level_requests) {
- OpenURL(url, referrer, info.defaultPolicy, info.replacesCurrentHistoryItem,
- false);
+ OpenURL(url, IsHttpPost(info.urlRequest),
+ GetRequestBodyForWebURLRequest(info.urlRequest), referrer,
+ info.defaultPolicy, info.replacesCurrentHistoryItem, false);
return blink::WebNavigationPolicyIgnore; // Suppress the load here.
}
@@ -4803,8 +4943,9 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
// FrameNavigationEntry. If none is found, fall back to the default url.
if (SiteIsolationPolicy::UseSubframeNavigationEntries() &&
info.isHistoryNavigationInNewChildFrame && is_content_initiated) {
- OpenURL(url, referrer, info.defaultPolicy, info.replacesCurrentHistoryItem,
- true);
+ OpenURL(url, IsHttpPost(info.urlRequest),
+ GetRequestBodyForWebURLRequest(info.urlRequest), referrer,
+ info.defaultPolicy, info.replacesCurrentHistoryItem, true);
// Suppress the load in Blink but mark the frame as loading.
return blink::WebNavigationPolicyHandledByClient;
}
@@ -4819,15 +4960,6 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
// an extension or app origin, leaving a WebUI page, etc). We only care about
// top-level navigations (not iframes). But we sometimes navigate to
// about:blank to clear a tab, and we want to still allow that.
- //
- // Note: this is known to break POST submissions when crossing process
- // boundaries until http://crbug.com/101395 is fixed. This is better for
- // security than loading a WebUI, extension or app page in the wrong process.
- // POST requests don't work because this mechanism does not preserve form
- // POST data. We will need to send the request's httpBody data up to the
- // browser process, and issue a special POST navigation in WebKit (via
- // FrameLoader::loadFrameRequest). See ResourceDispatcher and WebURLLoaderImpl
- // for examples of how to send the httpBody data.
if (!frame_->parent() && is_content_initiated &&
!url.SchemeIs(url::kAboutScheme)) {
bool send_referrer = false;
@@ -4867,7 +4999,9 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
}
if (should_fork) {
- OpenURL(url, send_referrer ? referrer : Referrer(), info.defaultPolicy,
+ OpenURL(url, IsHttpPost(info.urlRequest),
+ GetRequestBodyForWebURLRequest(info.urlRequest),
+ send_referrer ? referrer : Referrer(), info.defaultPolicy,
info.replacesCurrentHistoryItem, false);
return blink::WebNavigationPolicyIgnore; // Suppress the load here.
}
@@ -4907,11 +5041,31 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
if (is_fork) {
// Open the URL via the browser, not via WebKit.
- OpenURL(url, Referrer(), info.defaultPolicy,
- info.replacesCurrentHistoryItem, false);
+ OpenURL(url, IsHttpPost(info.urlRequest),
+ GetRequestBodyForWebURLRequest(info.urlRequest), Referrer(),
+ info.defaultPolicy, info.replacesCurrentHistoryItem, false);
return blink::WebNavigationPolicyIgnore;
}
+ // Execute the BeforeUnload event. If asked not to proceed or the frame is
+ // destroyed, ignore the navigation. There is no need to execute the
+ // BeforeUnload event during a redirect, since it was already executed at the
+ // start of the navigation.
+ // PlzNavigate: this is not executed when commiting the navigation.
+ if (info.defaultPolicy == blink::WebNavigationPolicyCurrentTab &&
+ !is_redirect && (!IsBrowserSideNavigationEnabled() ||
+ info.urlRequest.checkForBrowserSideNavigation())) {
+ // Keep a WeakPtr to this RenderFrameHost to detect if executing the
+ // BeforeUnload event destriyed this frame.
+ base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
+
+ if (!frame_->dispatchBeforeUnloadEvent(info.navigationType ==
+ blink::WebNavigationTypeReload) ||
+ !weak_self) {
+ return blink::WebNavigationPolicyIgnore;
+ }
+ }
+
// PlzNavigate: if the navigation is not synchronous, send it to the browser.
// This includes navigations with no request being sent to the network stack.
if (IsBrowserSideNavigationEnabled() &&
@@ -4965,30 +5119,36 @@ void RenderFrameImpl::OnSerializeAsMHTML(
DCHECK(!mhtml_boundary.isEmpty());
WebData data;
- bool success = true;
std::set<std::string> digests_of_uris_of_serialized_resources;
MHTMLPartsGenerationDelegate delegate(
params, &digests_of_uris_of_serialized_resources);
+ bool success = true;
+
// Generate MHTML header if needed.
if (IsMainFrame()) {
- blink::WebFrameSerializerCacheControlPolicy policy =
- static_cast<blink::WebFrameSerializerCacheControlPolicy>(
- params.mhtml_cache_control_policy);
- success = WebFrameSerializer::generateMHTMLHeader(mhtml_boundary, policy,
- GetWebFrame(), &data);
- if (success && file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
+ // |data| can be empty if the main frame should be skipped. If the main
+ // frame is
+ // skipped, then the whole archive is bad, so bail to the error condition.
+ WebData data = WebFrameSerializer::generateMHTMLHeader(
+ mhtml_boundary, GetWebFrame(), &delegate);
+ if (data.isEmpty() ||
+ file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
success = false;
}
}
- // Generate MHTML parts.
+ // Generate MHTML parts. Note that if this is not the main frame, then even
+ // skipping the whole parts generation step is not an error - it simply
+ // results in an omitted resource in the final file.
if (success) {
- data = WebFrameSerializer::generateMHTMLParts(
- mhtml_boundary, GetWebFrame(), params.mhtml_binary_encoding, &delegate);
+ // |data| can be empty if the frame should be skipped, but this is OK.
+ data = WebFrameSerializer::generateMHTMLParts(mhtml_boundary, GetWebFrame(),
+ &delegate);
// TODO(jcivelli): write the chunks in deferred tasks to give a chance to
// the message loop to process other events.
- if (file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
+ if (!data.isEmpty() &&
+ file.WriteAtCurrentPos(data.data(), data.size()) < 0) {
success = false;
}
}
@@ -5011,13 +5171,6 @@ void RenderFrameImpl::OnSerializeAsMHTML(
void RenderFrameImpl::OnFind(int request_id,
const base::string16& search_text,
const WebFindOptions& options) {
- // This should only be received on the main frame, since find-in-page is
- // currently orchestrated by the main frame.
- if (!is_main_frame_) {
- NOTREACHED();
- return;
- }
-
DCHECK(!search_text.empty());
blink::WebPlugin* plugin = GetWebPluginForFind();
@@ -5025,156 +5178,82 @@ void RenderFrameImpl::OnFind(int request_id,
if (plugin) {
if (options.findNext) {
// Just navigate back/forward.
- plugin->selectFindResult(options.forward);
+ plugin->selectFindResult(options.forward, request_id);
} else {
if (!plugin->startFind(search_text, options.matchCase, request_id)) {
// Send "no results".
- SendFindReply(request_id, 0, 0, gfx::Rect(), true);
+ SendFindReply(request_id, 0 /* match_count */, 0 /* ordinal */,
+ gfx::Rect(), true /* final_status_update */ );
}
}
return;
}
- WebLocalFrame* main_frame = GetWebFrame();
- WebLocalFrame* focused_frame =
- render_view_->webview()->focusedFrame()->toWebLocalFrame();
- // Start searching in the focused frame.
- WebLocalFrame* search_frame = focused_frame;
-
- // Check for multiple searchable frames.
- bool multi_frame = (main_frame->traverseNextLocal(true) != main_frame);
-
- // If we have multiple frames, we don't want to wrap the search within the
- // frame, so we check here if we only have |main_frame| in the chain.
- bool wrap_within_frame = !multi_frame;
+ // Send "no results" if this frame has no visible content.
+ if (!frame_->hasVisibleContent()) {
+ SendFindReply(request_id, 0 /* match_count */, 0 /* ordinal */,
+ gfx::Rect(), true /* final_status_update */ );
+ return;
+ }
WebRect selection_rect;
- bool result = false;
bool active_now = false;
// If something is selected when we start searching it means we cannot just
// increment the current match ordinal; we need to re-generate it.
- WebRange current_selection = focused_frame->selectionRange();
-
- do {
- result =
- search_frame->find(request_id, search_text, options, wrap_within_frame,
- &selection_rect, &active_now);
-
- if (!result) {
- // Don't leave text selected as you move to the next frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
-
- // Find the next frame, but skip the invisible ones.
- do {
- // What is the next frame to search (we might be going backwards)? Note
- // that we specify wrap=true so that search_frame never becomes NULL.
- search_frame = options.forward
- ? search_frame->traverseNextLocal(true)
- : search_frame->traversePreviousLocal(true);
- } while (!search_frame->hasVisibleContent() &&
- search_frame != focused_frame);
-
- // Make sure selection doesn't affect the search operation in new frame.
- search_frame->executeCommand(WebString::fromUTF8("Unselect"));
-
- // If we have multiple frames and we have wrapped back around to the
- // focused frame, we need to search it once more allowing wrap within
- // the frame, otherwise it will report 'no match' if the focused frame has
- // reported matches, but no frames after the focused_frame contain a
- // match for the search word(s).
- if (multi_frame && search_frame == focused_frame) {
- result = search_frame->find(request_id, search_text, options,
- true, // Force wrapping.
- &selection_rect, &active_now);
- }
- }
+ WebRange current_selection = frame_->selectionRange();
- render_view_->webview()->setFocusedFrame(search_frame);
- } while (!result && search_frame != focused_frame);
+ if (frame_->find(request_id, search_text, options,
+ false /* wrapWithinFrame */, &selection_rect, &active_now)) {
+ // Indicate that at least one match has been found. 1 here means possibly
+ // more matches could be coming. -1 here means that the exact active match
+ // ordinal is not yet known.
+ SendFindReply(request_id, 1 /* match_count */, -1 /* ordinal */,
+ gfx::Rect(), false /* final_status_update */ );
+ }
if (options.findNext && current_selection.isNull() && active_now) {
- // Force the main_frame to report the actual count.
- main_frame->increaseMatchCount(0, request_id);
- } else {
- // If nothing is found, set result to "0 of 0", otherwise, set it to
- // "-1 of 1" to indicate that we found at least one item, but we don't know
- // yet what is active.
- int ordinal = result ? -1 : 0; // -1 here means we might know more later.
- int match_count = result ? 1 : 0; // 1 here means possibly more coming.
-
- // If we find no matches then this will be our last status update.
- // Otherwise the scoping effort will send more results.
- bool final_status_update = !result;
-
- SendFindReply(request_id, match_count, ordinal, selection_rect,
- final_status_update);
-
- // Scoping effort begins, starting with the main frame.
- search_frame = main_frame;
-
- main_frame->resetMatchCount();
-
- do {
- // Cancel all old scoping requests before starting a new one.
- search_frame->cancelPendingScopingEffort();
-
- // We don't start another scoping effort unless at least one match has
- // been found.
- if (result) {
- // Start new scoping request. If the scoping function determines that it
- // needs to scope, it will defer until later.
- search_frame->scopeStringMatches(request_id, search_text, options,
- true); // reset the tickmarks
- }
-
- // Iterate to the next frame. The frame will not necessarily scope, for
- // example if it is not visible.
- search_frame = search_frame->traverseNextLocal(true);
- } while (search_frame != main_frame);
+ // Force report of the actual count.
+ frame_->increaseMatchCount(0, request_id);
+ return;
}
+
+ // Scoping effort begins.
+ frame_->resetMatchCount();
+
+ // Cancel all old scoping requests before starting a new one.
+ frame_->cancelPendingScopingEffort();
+
+ // Start new scoping request. If the scoping function determines that it
+ // needs to scope, it will defer until later.
+ frame_->scopeStringMatches(request_id,
+ search_text,
+ options,
+ true); // reset the tickmarks
}
-void RenderFrameImpl::OnStopFinding(StopFindAction action) {
- // This should only be received on the main frame, since find-in-page is
- // currently orchestrated by the main frame.
- if (!is_main_frame_) {
- NOTREACHED();
- return;
- }
+void RenderFrameImpl::OnClearActiveFindMatch() {
+ frame_->executeCommand(WebString::fromUTF8("Unselect"));
+ frame_->clearActiveFindMatch();
+}
- WebView* view = render_view_->webview();
- if (!view)
- return;
+// Ensure that content::StopFindAction and blink::WebLocalFrame::StopFindAction
+// are kept in sync.
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_CLEAR_SELECTION,
+ WebLocalFrame::StopFindActionClearSelection);
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_KEEP_SELECTION,
+ WebLocalFrame::StopFindActionKeepSelection);
+STATIC_ASSERT_ENUM(STOP_FIND_ACTION_ACTIVATE_SELECTION,
+ WebLocalFrame::StopFindActionActivateSelection);
+void RenderFrameImpl::OnStopFinding(StopFindAction action) {
blink::WebPlugin* plugin = GetWebPluginForFind();
if (plugin) {
plugin->stopFind();
return;
}
- bool clear_selection = action == STOP_FIND_ACTION_CLEAR_SELECTION;
- if (clear_selection) {
- view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
- }
-
- WebLocalFrame* frame = GetWebFrame();
- while (frame) {
- frame->stopFinding(clear_selection);
- frame = frame->traverseNextLocal(false);
- }
-
- if (action == STOP_FIND_ACTION_ACTIVATE_SELECTION) {
- WebFrame* focused_frame = view->focusedFrame();
- if (focused_frame) {
- WebDocument doc = focused_frame->document();
- if (!doc.isNull()) {
- WebElement element = doc.focusedElement();
- if (!element.isNull())
- element.simulateClick();
- }
- }
- }
+ frame_->stopFinding(static_cast<WebLocalFrame::StopFindAction>(action));
}
void RenderFrameImpl::OnEnableViewSourceMode() {
@@ -5187,6 +5266,43 @@ void RenderFrameImpl::OnSuppressFurtherDialogs() {
suppress_further_dialogs_ = true;
}
+void RenderFrameImpl::OnFileChooserResponse(
+ const std::vector<content::FileChooserFileInfo>& files) {
+ // This could happen if we navigated to a different page before the user
+ // closed the chooser.
+ if (file_chooser_completions_.empty())
+ return;
+
+ // Convert Chrome's SelectedFileInfo list to WebKit's.
+ WebVector<blink::WebFileChooserCompletion::SelectedFileInfo> selected_files(
+ files.size());
+ for (size_t i = 0; i < files.size(); ++i) {
+ blink::WebFileChooserCompletion::SelectedFileInfo selected_file;
+ selected_file.path = files[i].file_path.AsUTF16Unsafe();
+ selected_file.displayName =
+ base::FilePath(files[i].display_name).AsUTF16Unsafe();
+ if (files[i].file_system_url.is_valid()) {
+ selected_file.fileSystemURL = files[i].file_system_url;
+ selected_file.length = files[i].length;
+ selected_file.modificationTime = files[i].modification_time.ToDoubleT();
+ selected_file.isDirectory = files[i].is_directory;
+ }
+ selected_files[i] = selected_file;
+ }
+
+ if (file_chooser_completions_.front()->completion) {
+ file_chooser_completions_.front()->completion->didChooseFile(
+ selected_files);
+ }
+ file_chooser_completions_.pop_front();
+
+ // If there are more pending file chooser requests, schedule one now.
+ if (!file_chooser_completions_.empty()) {
+ Send(new FrameHostMsg_RunFileChooser(
+ routing_id_, file_chooser_completions_.front()->params));
+ }
+}
+
#if defined(OS_ANDROID)
void RenderFrameImpl::OnActivateNearestFindResult(int request_id,
float x,
@@ -5206,6 +5322,14 @@ void RenderFrameImpl::OnActivateNearestFindResult(int request_id,
true /* final_update */);
}
+void RenderFrameImpl::OnGetNearestFindResult(int nfr_request_id,
+ float x,
+ float y) {
+ float distance = frame_->distanceToNearestFindMatch(WebFloatPoint(x, y));
+ Send(new FrameHostMsg_GetNearestFindResult_Reply(
+ routing_id_, nfr_request_id, distance));
+}
+
void RenderFrameImpl::OnFindMatchRects(int current_version) {
std::vector<gfx::RectF> match_rects;
@@ -5222,7 +5346,17 @@ void RenderFrameImpl::OnFindMatchRects(int current_version) {
Send(new FrameHostMsg_FindMatchRects_Reply(routing_id_, rects_version,
match_rects, active_rect));
}
+#endif
+#if defined(USE_EXTERNAL_POPUP_MENU)
+#if defined(OS_MACOSX)
+void RenderFrameImpl::OnSelectPopupMenuItem(int selected_index) {
+ if (external_popup_menu_ == NULL)
+ return;
+ external_popup_menu_->DidSelectItem(selected_index);
+ external_popup_menu_.reset();
+}
+#else
void RenderFrameImpl::OnSelectPopupMenuItems(
bool canceled,
const std::vector<int>& selected_indices) {
@@ -5236,22 +5370,21 @@ void RenderFrameImpl::OnSelectPopupMenuItems(
external_popup_menu_->DidSelectItems(canceled, selected_indices);
external_popup_menu_.reset();
}
-#elif defined(OS_MACOSX)
-void RenderFrameImpl::OnSelectPopupMenuItem(int selected_index) {
- if (external_popup_menu_ == NULL)
- return;
- external_popup_menu_->DidSelectItem(selected_index);
- external_popup_menu_.reset();
-}
+#endif
#endif
-void RenderFrameImpl::OpenURL(const GURL& url,
- const Referrer& referrer,
- WebNavigationPolicy policy,
- bool should_replace_current_entry,
- bool is_history_navigation_in_new_child) {
+void RenderFrameImpl::OpenURL(
+ const GURL& url,
+ bool uses_post,
+ const scoped_refptr<ResourceRequestBodyImpl>& resource_request_body,
+ const Referrer& referrer,
+ WebNavigationPolicy policy,
+ bool should_replace_current_entry,
+ bool is_history_navigation_in_new_child) {
FrameHostMsg_OpenURL_Params params;
params.url = url;
+ params.uses_post = uses_post;
+ params.resource_request_body = resource_request_body;
params.referrer = referrer;
params.disposition = RenderViewImpl::NavigationPolicyToDisposition(policy);
@@ -5349,6 +5482,12 @@ void RenderFrameImpl::NavigateInternal(
WebURLRequest request =
CreateURLRequestForNavigation(common_params, std::move(stream_params),
frame_->isViewSourceModeEnabled());
+ request.setFrameType(IsTopLevelNavigation(frame_)
+ ? blink::WebURLRequest::FrameTypeTopLevel
+ : blink::WebURLRequest::FrameTypeNested);
+
+ if (IsBrowserSideNavigationEnabled() && common_params.post_data)
+ request.setHTTPBody(GetWebHTTPBodyForRequestBody(common_params.post_data));
// Used to determine whether this frame is actually loading a request as part
// of a history navigation.
@@ -5439,18 +5578,10 @@ void RenderFrameImpl::NavigateInternal(
}
}
- if (common_params.method == "POST" && !browser_side_navigation) {
- // Set post data.
- WebHTTPBody http_body;
- http_body.initialize();
- const char* data = nullptr;
- if (start_params.browser_initiated_post_data.size()) {
- data = reinterpret_cast<const char*>(
- &start_params.browser_initiated_post_data.front());
- }
- http_body.appendData(
- WebData(data, start_params.browser_initiated_post_data.size()));
- request.setHTTPBody(http_body);
+ if (common_params.method == "POST" && !browser_side_navigation &&
+ common_params.post_data) {
+ request.setHTTPBody(
+ GetWebHTTPBodyForRequestBody(common_params.post_data));
}
// A session history navigation should have been accompanied by state.
@@ -5474,12 +5605,11 @@ void RenderFrameImpl::NavigateInternal(
// Perform a navigation to a data url if needed.
// Note: the base URL might be invalid, so also check the data URL string.
- if (!common_params.base_url_for_data_url.is_empty() ||
+ bool should_load_data_url = !common_params.base_url_for_data_url.is_empty();
#if defined(OS_ANDROID)
- !request_params.data_url_as_string.empty() ||
+ should_load_data_url |= !request_params.data_url_as_string.empty();
#endif
- (browser_side_navigation &&
- common_params.url.SchemeIs(url::kDataScheme))) {
+ if (should_load_data_url) {
LoadDataURL(common_params, request_params, frame_, load_type,
item_for_history_navigation, history_load_type,
is_client_redirect);
@@ -5605,11 +5735,12 @@ WebMediaPlayer* RenderFrameImpl::CreateWebMediaPlayerForMediaStream(
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
render_thread->compositor_task_runner();
if (!compositor_task_runner.get())
- compositor_task_runner = base::MessageLoop::current()->task_runner();
+ compositor_task_runner = base::ThreadTaskRunnerHandle::Get();
return new WebMediaPlayerMS(
frame_, client, GetWebMediaPlayerDelegate()->AsWeakPtr(),
- new RenderMediaLog(), CreateRendererFactory(), compositor_task_runner,
+ new RenderMediaLog(blink::WebStringToGURL(security_origin.toString())),
+ CreateRendererFactory(), compositor_task_runner,
render_thread->GetMediaThreadTaskRunner(),
render_thread->GetWorkerTaskRunner(), render_thread->GetGpuFactories(),
sink_id, security_origin);
@@ -5660,7 +5791,6 @@ void RenderFrameImpl::BeginNavigation(blink::WebURLRequest* request,
bool is_client_redirect) {
CHECK(IsBrowserSideNavigationEnabled());
DCHECK(request);
- // TODO(clamy): Execute the beforeunload event.
// Note: At this stage, the goal is to apply all the modifications the
// renderer wants to make to the request, and then send it to the browser, so
@@ -5708,9 +5838,9 @@ void RenderFrameImpl::BeginNavigation(blink::WebURLRequest* request,
BeginNavigationParams(GetWebURLRequestHeaders(*request),
GetLoadFlagsForWebURLRequest(*request),
request->hasUserGesture(),
- request->skipServiceWorker(),
- GetRequestContextTypeForWebURLRequest(*request)),
- GetRequestBodyForWebURLRequest(*request)));
+ request->skipServiceWorker() !=
+ blink::WebURLRequest::SkipServiceWorker::None,
+ GetRequestContextTypeForWebURLRequest(*request))));
}
void RenderFrameImpl::LoadDataURL(
@@ -6028,23 +6158,23 @@ media::DecoderFactory* RenderFrameImpl::GetDecoderFactory() {
return decoder_factory_.get();
}
-void RenderFrameImpl::RegisterMojoServices() {
+void RenderFrameImpl::RegisterMojoInterfaces() {
// Only main frame have ImageDownloader service.
if (!frame_->parent()) {
- GetServiceRegistry()->AddService(base::Bind(
+ GetInterfaceRegistry()->AddInterface(base::Bind(
&ImageDownloaderImpl::CreateMojoService, base::Unretained(this)));
}
}
template <typename Interface>
void RenderFrameImpl::GetInterface(mojo::InterfaceRequest<Interface> request) {
- GetServiceRegistry()->ConnectToRemoteService(std::move(request));
+ GetRemoteInterfaces()->GetInterface(std::move(request));
}
shell::mojom::InterfaceProviderPtr RenderFrameImpl::ConnectToApplication(
const GURL& url) {
if (!connector_)
- GetServiceRegistry()->ConnectToRemoteService(mojo::GetProxy(&connector_));
+ GetRemoteInterfaces()->GetInterface(&connector_);
shell::mojom::InterfaceProviderPtr interface_provider;
shell::mojom::IdentityPtr target(shell::mojom::Identity::New());
target->name = url.spec();
@@ -6074,13 +6204,28 @@ void RenderFrameImpl::checkIfAudioSinkExistsAndIsAuthorized(
}
blink::ServiceRegistry* RenderFrameImpl::serviceRegistry() {
- return &blink_service_registry_;
+ return blink_service_registry_.get();
}
-blink::WebPlugin* RenderFrameImpl::GetWebPluginForFind() {
- if (!is_main_frame_)
- return nullptr;
+blink::WebPageVisibilityState RenderFrameImpl::visibilityState() const {
+ RenderFrameImpl* local_root =
+ RenderFrameImpl::FromWebFrame(frame_->localRoot());
+ blink::WebPageVisibilityState current_state =
+ local_root->render_widget_->is_hidden()
+ ? blink::WebPageVisibilityStateHidden
+ : blink::WebPageVisibilityStateVisible;
+ blink::WebPageVisibilityState override_state = current_state;
+ if (GetContentClient()->renderer()->ShouldOverridePageVisibilityState(
+ this, &override_state))
+ return override_state;
+ return current_state;
+}
+blink::WebPageVisibilityState RenderFrameImpl::GetVisibilityState() const {
+ return visibilityState();
+}
+
+blink::WebPlugin* RenderFrameImpl::GetWebPluginForFind() {
if (frame_->document().isPluginDocument())
return frame_->document().to<WebPluginDocument>().plugin();
@@ -6097,8 +6242,15 @@ void RenderFrameImpl::SendFindReply(int request_id,
int ordinal,
const WebRect& selection_rect,
bool final_status_update) {
- Send(new FrameHostMsg_Find_Reply(routing_id_, request_id, match_count,
- selection_rect, ordinal,
+ if (final_status_update && !ordinal)
+ frame_->executeCommand(WebString::fromUTF8("Unselect"));
+ DCHECK(ordinal >= -1);
+
+ Send(new FrameHostMsg_Find_Reply(routing_id_,
+ request_id,
+ match_count,
+ selection_rect,
+ ordinal,
final_status_update));
}
@@ -6137,6 +6289,22 @@ void RenderFrameImpl::PepperFocusChanged(PepperPluginInstanceImpl* instance,
GetRenderWidget()->UpdateSelectionBounds();
}
+void RenderFrameImpl::PepperStartsPlayback(PepperPluginInstanceImpl* instance) {
+ // TODO(zqzhang): send PepperStartsPlayback message to the browser.
+ // See https://crbug.com/619084
+}
+
+void RenderFrameImpl::PepperStopsPlayback(PepperPluginInstanceImpl* instance) {
+ // TODO(zqzhang): send PepperStopsPlayback message to the browser.
+ // See https://crbug.com/619084
+}
+
+void RenderFrameImpl::OnSetPepperVolume(int32_t pp_instance, double volume) {
+ PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>(
+ PepperPluginInstance::Get(pp_instance));
+ if (instance)
+ instance->audio_controller().SetVolume(volume);
+}
#endif // ENABLE_PLUGINS
void RenderFrameImpl::RenderWidgetSetFocus(bool enable) {
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index c424e0a6002..f3d5f6f9efa 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -17,13 +17,14 @@
#include "base/id_map.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/process/process_handle.h"
#include "build/build_config.h"
#include "content/common/accessibility_mode_enums.h"
+#include "content/common/frame.mojom.h"
#include "content/common/frame_message_enums.h"
-#include "content/common/mojo/service_registry_impl.h"
#include "content/public/common/console_message_level.h"
#include "content/public/common/javascript_message_type.h"
#include "content/public/common/referrer.h"
@@ -36,12 +37,14 @@
#include "ipc/ipc_platform_file.h"
#include "media/blink/webmediaplayer_delegate.h"
#include "media/blink/webmediaplayer_params.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "services/shell/public/interfaces/connector.mojom.h"
#include "services/shell/public/interfaces/interface_provider.mojom.h"
#include "third_party/WebKit/public/platform/WebEffectiveConnectionType.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
#include "third_party/WebKit/public/platform/WebLoadingBehaviorFlag.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
+#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerClient.h"
#include "third_party/WebKit/public/web/WebAXObject.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
@@ -108,8 +111,9 @@ class UrlIndex;
class WebEncryptedMediaClientImpl;
}
-namespace mojo {
-class ServiceProvider;
+namespace shell {
+class InterfaceRegistry;
+class InterfaceProvider;
}
namespace url {
@@ -136,7 +140,7 @@ class PepperPluginInstanceImpl;
class PermissionDispatcher;
class PresentationDispatcher;
class PushMessagingDispatcher;
-class RendererAccessibility;
+class RenderAccessibilityImpl;
class RendererCdmManager;
class RendererMediaPlayerManager;
class RendererMediaSessionManager;
@@ -146,11 +150,14 @@ class RenderFrameObserver;
class RenderViewImpl;
class RenderWidget;
class RenderWidgetFullscreenPepper;
+class ResourceRequestBodyImpl;
class ScreenOrientationDispatcher;
class UserMediaClientImpl;
class WakeLockDispatcher;
struct CommonNavigationParams;
struct CustomContextMenuContext;
+struct FileChooserFileInfo;
+struct FileChooserParams;
struct FrameReplicationState;
struct NavigationParams;
struct RequestNavigationParams;
@@ -160,6 +167,7 @@ struct StreamOverrideParameters;
class CONTENT_EXPORT RenderFrameImpl
: public RenderFrame,
+ NON_EXPORTED_BASE(mojom::Frame),
NON_EXPORTED_BASE(public blink::WebFrameClient),
NON_EXPORTED_BASE(public blink::WebFrameSerializerClient) {
public:
@@ -279,8 +287,8 @@ class CONTENT_EXPORT RenderFrameImpl
return accessibility_mode_;
}
- RendererAccessibility* renderer_accessibility() {
- return renderer_accessibility_;
+ RenderAccessibilityImpl* render_accessibility() {
+ return render_accessibility_;
}
void HandleWebAccessibilityEvent(const blink::WebAXObject& obj,
@@ -291,7 +299,7 @@ class CONTENT_EXPORT RenderFrameImpl
void FocusedNodeChanged(const blink::WebNode& node);
// TODO(dmazzoni): the only reason this is here is to plumb it through to
- // RendererAccessibility. It should use the RenderFrameObserver method, once
+ // RenderAccessibilityImpl. It should use the RenderFrameObserver method, once
// blink has a separate accessibility tree per frame.
void FocusedNodeChangedForAccessibility(const blink::WebNode& node);
@@ -367,7 +375,7 @@ class CONTENT_EXPORT RenderFrameImpl
// NULL.
MediaStreamDispatcher* GetMediaStreamDispatcher();
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(USE_EXTERNAL_POPUP_MENU)
void DidHideExternalPopupMenu();
#endif
@@ -379,6 +387,7 @@ class CONTENT_EXPORT RenderFrameImpl
// RenderFrame implementation:
RenderView* GetRenderView() override;
+ RenderAccessibility* GetRenderAccessibility() override;
int GetRoutingID() override;
blink::WebLocalFrame* GetWebFrame() override;
WebPreferences& GetWebkitPreferences() override;
@@ -395,7 +404,8 @@ class CONTENT_EXPORT RenderFrameImpl
void ExecuteJavaScript(const base::string16& javascript) override;
bool IsMainFrame() override;
bool IsHidden() override;
- ServiceRegistry* GetServiceRegistry() override;
+ shell::InterfaceRegistry* GetInterfaceRegistry() override;
+ shell::InterfaceProvider* GetRemoteInterfaces() override;
#if defined(ENABLE_PLUGINS)
void RegisterPeripheralPlugin(
const url::Origin& content_origin,
@@ -418,6 +428,11 @@ class CONTENT_EXPORT RenderFrameImpl
const std::string& message) override;
bool IsUsingLoFi() const override;
bool IsPasting() const override;
+ blink::WebPageVisibilityState GetVisibilityState() const override;
+
+ // mojom::Frame implementation:
+ void GetInterfaceProvider(
+ shell::mojom::InterfaceProviderRequest request) override;
// blink::WebFrameClient implementation:
blink::WebPlugin* createPlugin(blink::WebLocalFrame* frame,
@@ -454,7 +469,8 @@ class CONTENT_EXPORT RenderFrameImpl
void willClose(blink::WebFrame* frame) override;
void didChangeName(const blink::WebString& name,
const blink::WebString& unique_name) override;
- void didEnforceStrictMixedContentChecking() override;
+ void didEnforceInsecureRequestPolicy(
+ blink::WebInsecureRequestPolicy policy) override;
void didUpdateToUniqueOrigin(
bool is_potentially_trustworthy_unique_origin) override;
void didChangeSandboxFlags(blink::WebFrame* child_frame,
@@ -539,7 +555,11 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebString& default_value,
blink::WebString* actual_value) override;
bool runModalBeforeUnloadDialog(bool is_reload) override;
+ bool runFileChooser(
+ const blink::WebFileChooserParams& params,
+ blink::WebFileChooserCompletion* chooser_completion) override;
void showContextMenu(const blink::WebContextMenuData& data) override;
+ void saveImageFromDataURL(const blink::WebString& data_url) override;
void willSendRequest(blink::WebLocalFrame* frame,
unsigned identifier,
blink::WebURLRequest& request,
@@ -618,6 +638,7 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebSecurityOrigin& security_origin,
blink::WebSetSinkIdCallbacks* web_callbacks) override;
blink::ServiceRegistry* serviceRegistry() override;
+ blink::WebPageVisibilityState visibilityState() const override;
// WebFrameSerializerClient implementation:
void didSerializeDataForFrame(
@@ -625,9 +646,8 @@ class CONTENT_EXPORT RenderFrameImpl
blink::WebFrameSerializerClient::FrameSerializationStatus status)
override;
- // Binds this render frame's service registry.
- void BindServiceRegistry(shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services);
+ // Binds to the FrameHost in the browser.
+ void Bind(mojom::FrameRequest frame, mojom::FrameHostPtr frame_host);
ManifestManager* manifest_manager();
@@ -670,6 +690,10 @@ class CONTENT_EXPORT RenderFrameImpl
// Notification that the given plugin is focused or unfocused.
void PepperFocusChanged(PepperPluginInstanceImpl* instance, bool focused);
+
+ void PepperStartsPlayback(PepperPluginInstanceImpl* instance);
+ void PepperStopsPlayback(PepperPluginInstanceImpl* instance);
+ void OnSetPepperVolume(int32_t pp_instance, double volume);
#endif // ENABLE_PLUGINS
protected:
@@ -678,13 +702,13 @@ class CONTENT_EXPORT RenderFrameImpl
private:
friend class RenderFrameImplTest;
friend class RenderFrameObserver;
- friend class RendererAccessibilityTest;
+ friend class RenderAccessibilityImplTest;
friend class TestRenderFrame;
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuDisplayNoneTest, SelectItem);
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveOnChange);
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, NormalCase);
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate);
- FRIEND_TEST_ALL_PREFIXES(RendererAccessibilityTest,
+ FRIEND_TEST_ALL_PREFIXES(RenderAccessibilityImplTest,
AccessibilityMessagesQueueWhileSwappedOut);
// A wrapper class used as the callback for JavaScript executed
@@ -741,7 +765,7 @@ class CONTENT_EXPORT RenderFrameImpl
void OnNavigate(const CommonNavigationParams& common_params,
const StartNavigationParams& start_params,
const RequestNavigationParams& request_params);
- void OnBeforeUnload();
+ void OnBeforeUnload(bool is_reload);
void OnSwapOut(int proxy_routing_id,
bool is_loading,
const FrameReplicationState& replicated_frame_state);
@@ -765,6 +789,8 @@ class CONTENT_EXPORT RenderFrameImpl
void OnMoveRangeSelectionExtent(const gfx::Point& point);
void OnReplace(const base::string16& text);
void OnReplaceMisspelling(const base::string16& text);
+ void OnCopyImageAt(int x, int y);
+ void OnSaveImageAt(int x, int y);
void OnCSSInsertRequest(const std::string& css);
void OnAddMessageToConsole(ConsoleMessageLevel level,
const std::string& message);
@@ -816,16 +842,28 @@ class CONTENT_EXPORT RenderFrameImpl
void OnFind(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options);
+ void OnClearActiveFindMatch();
void OnStopFinding(StopFindAction action);
void OnEnableViewSourceMode();
void OnSuppressFurtherDialogs();
+ void OnFileChooserResponse(
+ const std::vector<content::FileChooserFileInfo>& files);
#if defined(OS_ANDROID)
void OnActivateNearestFindResult(int request_id, float x, float y);
+ void OnGetNearestFindResult(int request_id, float x, float y);
void OnFindMatchRects(int current_version);
+#endif
+
+#if defined(USE_EXTERNAL_POPUP_MENU)
+#if defined(OS_MACOSX)
+ void OnSelectPopupMenuItem(int selected_index);
+#else
void OnSelectPopupMenuItems(bool canceled,
const std::vector<int>& selected_indices);
-#elif defined(OS_MACOSX)
- void OnSelectPopupMenuItem(int selected_index);
+#endif
+#endif
+
+#if defined(OS_MACOSX)
void OnCopyToFindPboard();
#endif
@@ -833,11 +871,14 @@ class CONTENT_EXPORT RenderFrameImpl
// |is_history_navigation_in_new_child| is true, the browser process should
// look for a matching FrameNavigationEntry in the last committed entry to use
// instead of |url|.
- void OpenURL(const GURL& url,
- const Referrer& referrer,
- blink::WebNavigationPolicy policy,
- bool should_replace_current_entry,
- bool is_history_navigation_in_new_child);
+ void OpenURL(
+ const GURL& url,
+ bool uses_post,
+ const scoped_refptr<ResourceRequestBodyImpl>& resource_request_body,
+ const Referrer& referrer,
+ blink::WebNavigationPolicy policy,
+ bool should_replace_current_entry,
+ bool is_history_navigation_in_new_child);
// Performs a navigation in the frame. This provides a unified function for
// the current code path and the browser-side navigation path (in
@@ -881,6 +922,15 @@ class CONTENT_EXPORT RenderFrameImpl
const GURL& frame_url,
base::string16* result);
+ // Adds the given file chooser request to the file_chooser_completion_ queue
+ // (see that var for more) and requests the chooser be displayed if there are
+ // no other waiting items in the queue.
+ //
+ // Returns true if the chooser was successfully scheduled. False means we
+ // didn't schedule anything.
+ bool ScheduleFileChooser(const FileChooserParams& params,
+ blink::WebFileChooserCompletion* completion);
+
// Loads the appropriate error page for the specified failure into the frame.
void LoadNavigationErrorPage(const blink::WebURLRequest& failed_request,
const blink::WebURLError& error,
@@ -978,7 +1028,7 @@ class CONTENT_EXPORT RenderFrameImpl
media::CdmFactory* GetCdmFactory();
media::DecoderFactory* GetDecoderFactory();
- void RegisterMojoServices();
+ void RegisterMojoInterfaces();
// Connect to an interface provided by the service registry.
template <typename Interface>
@@ -1038,8 +1088,6 @@ class CONTENT_EXPORT RenderFrameImpl
base::WeakPtr<RenderViewImpl> render_view_;
int routing_id_;
- bool is_detaching_;
-
// If this frame was created to replace a proxy, this will store the routing
// id of the proxy to replace at commit-time, at which time it will be
// cleared.
@@ -1172,8 +1220,11 @@ class CONTENT_EXPORT RenderFrameImpl
// initialized.
PresentationDispatcher* presentation_dispatcher_;
- ServiceRegistryImpl service_registry_;
- BlinkServiceRegistryImpl blink_service_registry_;
+ std::unique_ptr<shell::InterfaceRegistry> interface_registry_;
+ std::unique_ptr<shell::InterfaceProvider> remote_interfaces_;
+ std::unique_ptr<BlinkServiceRegistryImpl> blink_service_registry_;
+ shell::mojom::InterfaceProviderRequest
+ pending_remote_interface_provider_request_;
// The shell proxy used to connect to Mojo applications.
shell::mojom::ConnectorPtr connector_;
@@ -1191,7 +1242,7 @@ class CONTENT_EXPORT RenderFrameImpl
// Only valid if |accessibility_mode_| is anything other than
// AccessibilityModeOff.
- RendererAccessibility* renderer_accessibility_;
+ RenderAccessibilityImpl* render_accessibility_;
std::unique_ptr<PermissionDispatcher> permission_client_;
@@ -1217,12 +1268,19 @@ class CONTENT_EXPORT RenderFrameImpl
// stack that interferes with swapping out.
bool suppress_further_dialogs_;
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+ // The current and pending file chooser completion objects. If the queue is
+ // nonempty, the first item represents the currently running file chooser
+ // callback, and the remaining elements are the other file chooser completion
+ // still waiting to be run (in order).
+ struct PendingFileChooser;
+ std::deque<std::unique_ptr<PendingFileChooser>> file_chooser_completions_;
+
+#if defined(USE_EXTERNAL_POPUP_MENU)
// The external popup for the currently showing select popup.
std::unique_ptr<ExternalPopupMenu> external_popup_menu_;
#endif
- FrameBlameContext* blame_context_; // Not owned.
+ std::unique_ptr<FrameBlameContext> blame_context_;
// Plugins -------------------------------------------------------------------
#if defined(ENABLE_PLUGINS)
@@ -1239,6 +1297,9 @@ class CONTENT_EXPORT RenderFrameImpl
PepperPluginInstanceImpl* pepper_last_mouse_event_target_;
#endif
+ mojo::Binding<mojom::Frame> frame_binding_;
+ mojom::FrameHostPtr frame_host_;
+
base::WeakPtrFactory<RenderFrameImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/chromium/content/renderer/render_frame_impl_browsertest.cc b/chromium/content/renderer/render_frame_impl_browsertest.cc
index 2a853c16903..61fd6b341e9 100644
--- a/chromium/content/renderer/render_frame_impl_browsertest.cc
+++ b/chromium/content/renderer/render_frame_impl_browsertest.cc
@@ -19,11 +19,14 @@
#include "content/test/fake_compositor_dependencies.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebEffectiveConnectionType.h"
+#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebFrameOwnerProperties.h"
#include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
+using blink::WebString;
+
namespace {
const int32_t kSubframeRouteId = 20;
const int32_t kSubframeWidgetRouteId = 21;
@@ -108,8 +111,10 @@ class RenderFrameTestObserver : public RenderFrameObserver {
~RenderFrameTestObserver() override {}
+ // RenderFrameObserver implementation.
void WasShown() override { visible_ = true; }
void WasHidden() override { visible_ = false; }
+ void OnDestruct() override { delete this; }
bool visible() { return visible_; }
@@ -292,4 +297,50 @@ TEST_F(RenderFrameImplTest, EffectiveConnectionType) {
}
}
+TEST_F(RenderFrameImplTest, SaveImageFromDataURL) {
+ const IPC::Message* msg1 = render_thread_->sink().GetFirstMessageMatching(
+ FrameHostMsg_SaveImageFromDataURL::ID);
+ EXPECT_FALSE(msg1);
+ render_thread_->sink().ClearMessages();
+
+ const std::string image_data_url =
+ "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
+
+ frame()->saveImageFromDataURL(WebString::fromUTF8(image_data_url));
+ ProcessPendingMessages();
+ const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching(
+ FrameHostMsg_SaveImageFromDataURL::ID);
+ EXPECT_TRUE(msg2);
+
+ FrameHostMsg_SaveImageFromDataURL::Param param1;
+ FrameHostMsg_SaveImageFromDataURL::Read(msg2, &param1);
+ EXPECT_EQ(std::get<2>(param1), image_data_url);
+
+ ProcessPendingMessages();
+ render_thread_->sink().ClearMessages();
+
+ const std::string large_data_url(1024 * 1024 * 20 - 1, 'd');
+
+ frame()->saveImageFromDataURL(WebString::fromUTF8(large_data_url));
+ ProcessPendingMessages();
+ const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching(
+ FrameHostMsg_SaveImageFromDataURL::ID);
+ EXPECT_TRUE(msg3);
+
+ FrameHostMsg_SaveImageFromDataURL::Param param2;
+ FrameHostMsg_SaveImageFromDataURL::Read(msg3, &param2);
+ EXPECT_EQ(std::get<2>(param2), large_data_url);
+
+ ProcessPendingMessages();
+ render_thread_->sink().ClearMessages();
+
+ const std::string exceeded_data_url(1024 * 1024 * 20 + 1, 'd');
+
+ frame()->saveImageFromDataURL(WebString::fromUTF8(exceeded_data_url));
+ ProcessPendingMessages();
+ const IPC::Message* msg4 = render_thread_->sink().GetFirstMessageMatching(
+ FrameHostMsg_SaveImageFromDataURL::ID);
+ EXPECT_FALSE(msg4);
+}
+
} // namespace
diff --git a/chromium/content/renderer/render_frame_proxy.cc b/chromium/content/renderer/render_frame_proxy.cc
index 868412155c7..74bcd08f83f 100644
--- a/chromium/content/renderer/render_frame_proxy.cc
+++ b/chromium/content/renderer/render_frame_proxy.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "content/child/web_url_request_util.h"
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/content_security_policy_header.h"
#include "content/common/frame_messages.h"
@@ -212,8 +213,7 @@ void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
web_frame_->setReplicatedSandboxFlags(state.sandbox_flags);
web_frame_->setReplicatedName(blink::WebString::fromUTF8(state.name),
blink::WebString::fromUTF8(state.unique_name));
- web_frame_->setReplicatedShouldEnforceStrictMixedContentChecking(
- state.should_enforce_strict_mixed_content_checking);
+ web_frame_->setReplicatedInsecureRequestPolicy(state.insecure_request_policy);
web_frame_->setReplicatedPotentiallyTrustworthyUniqueOrigin(
state.has_potentially_trustworthy_unique_origin);
@@ -267,11 +267,14 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
OnAddContentSecurityPolicy)
IPC_MESSAGE_HANDLER(FrameMsg_ResetContentSecurityPolicy,
OnResetContentSecurityPolicy)
- IPC_MESSAGE_HANDLER(FrameMsg_EnforceStrictMixedContentChecking,
- OnEnforceStrictMixedContentChecking)
+ IPC_MESSAGE_HANDLER(FrameMsg_EnforceInsecureRequestPolicy,
+ OnEnforceInsecureRequestPolicy)
+ IPC_MESSAGE_HANDLER(FrameMsg_SetFrameOwnerProperties,
+ OnSetFrameOwnerProperties)
IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateOrigin, OnDidUpdateOrigin)
IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetPageFocus)
IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame)
+ IPC_MESSAGE_HANDLER(FrameMsg_WillEnterFullscreen, OnWillEnterFullscreen)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -348,10 +351,14 @@ void RenderFrameProxy::OnResetContentSecurityPolicy() {
web_frame_->resetReplicatedContentSecurityPolicy();
}
-void RenderFrameProxy::OnEnforceStrictMixedContentChecking(
- bool should_enforce) {
- web_frame_->setReplicatedShouldEnforceStrictMixedContentChecking(
- should_enforce);
+void RenderFrameProxy::OnEnforceInsecureRequestPolicy(
+ blink::WebInsecureRequestPolicy policy) {
+ web_frame_->setReplicatedInsecureRequestPolicy(policy);
+}
+
+void RenderFrameProxy::OnSetFrameOwnerProperties(
+ const blink::WebFrameOwnerProperties& properties) {
+ web_frame_->setFrameOwnerProperties(properties);
}
void RenderFrameProxy::OnDidUpdateOrigin(
@@ -372,6 +379,10 @@ void RenderFrameProxy::OnSetFocusedFrame() {
render_view_->webview()->focusDocumentView(web_frame_);
}
+void RenderFrameProxy::OnWillEnterFullscreen() {
+ web_frame_->willEnterFullScreen();
+}
+
void RenderFrameProxy::frameDetached(DetachType type) {
if (type == DetachType::Remove && web_frame_->parent()) {
web_frame_->parent()->removeChild(web_frame_);
@@ -436,6 +447,8 @@ void RenderFrameProxy::navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry) {
FrameHostMsg_OpenURL_Params params;
params.url = request.url();
+ params.uses_post = request.httpMethod().utf8() == "POST";
+ params.resource_request_body = GetRequestBodyForWebURLRequest(request);
params.referrer = Referrer(
blink::WebStringToGURL(
request.httpHeaderField(blink::WebString::fromUTF8("Referer"))),
diff --git a/chromium/content/renderer/render_frame_proxy.h b/chromium/content/renderer/render_frame_proxy.h
index 638037b69d4..950e25dacd5 100644
--- a/chromium/content/renderer/render_frame_proxy.h
+++ b/chromium/content/renderer/render_frame_proxy.h
@@ -11,6 +11,7 @@
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/public/platform/WebFocusType.h"
+#include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h"
#include "third_party/WebKit/public/web/WebRemoteFrame.h"
#include "third_party/WebKit/public/web/WebRemoteFrameClient.h"
#include "url/origin.h"
@@ -24,7 +25,7 @@ struct WebRect;
}
namespace cc {
-struct SurfaceId;
+class SurfaceId;
struct SurfaceSequence;
}
@@ -168,11 +169,14 @@ class CONTENT_EXPORT RenderFrameProxy
void OnDidUpdateName(const std::string& name, const std::string& unique_name);
void OnAddContentSecurityPolicy(const ContentSecurityPolicyHeader& header);
void OnResetContentSecurityPolicy();
- void OnEnforceStrictMixedContentChecking(bool should_enforce);
+ void OnEnforceInsecureRequestPolicy(blink::WebInsecureRequestPolicy policy);
+ void OnSetFrameOwnerProperties(
+ const blink::WebFrameOwnerProperties& properties);
void OnDidUpdateOrigin(const url::Origin& origin,
bool is_potentially_trustworthy_unique_origin);
void OnSetPageFocus(bool is_focused);
void OnSetFocusedFrame();
+ void OnWillEnterFullscreen();
// The routing ID by which this RenderFrameProxy is known.
const int routing_id_;
diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc
index b729a8ca44e..a43b39dd21d 100644
--- a/chromium/content/renderer/render_thread_impl.cc
+++ b/chromium/content/renderer/render_thread_impl.cc
@@ -41,6 +41,8 @@
#include "cc/base/switches.h"
#include "cc/blink/web_external_bitmap_impl.h"
#include "cc/blink/web_layer_impl.h"
+#include "cc/output/output_surface.h"
+#include "cc/output/vulkan_in_process_context_provider.h"
#include "cc/raster/task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_settings.h"
@@ -65,15 +67,14 @@
#include "content/child/runtime_features.h"
#include "content/child/thread_safe_sender.h"
#include "content/child/web_database_observer_impl.h"
+#include "content/child/websocket_message_filter.h"
#include "content/child/worker_thread_registry.h"
#include "content/common/child_process_messages.h"
#include "content/common/content_constants_internal.h"
-#include "content/common/database_messages.h"
#include "content/common/dom_storage/dom_storage_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu_process_launch_causes.h"
-#include "content/common/render_frame_setup.mojom.h"
#include "content/common/render_process_messages.h"
#include "content/common/resource_messages.h"
#include "content/common/service_worker/embedded_worker_setup.mojom.h"
@@ -87,10 +88,10 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread_observer.h"
#include "content/public/renderer/render_view_visitor.h"
-#include "content/renderer/bluetooth/bluetooth_message_filter.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/cache_storage/cache_storage_dispatcher.h"
#include "content/renderer/cache_storage/cache_storage_message_filter.h"
+#include "content/renderer/categorized_worker_pool.h"
#include "content/renderer/devtools/devtools_agent_filter.h"
#include "content/renderer/devtools/v8_sampling_profiler.h"
#include "content/renderer/dom_storage/dom_storage_dispatcher.h"
@@ -99,6 +100,7 @@
#include "content/renderer/gpu/compositor_external_begin_frame_source.h"
#include "content/renderer/gpu/compositor_forwarding_message_filter.h"
#include "content/renderer/gpu/compositor_output_surface.h"
+#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/input/input_event_filter.h"
#include "content/renderer/input/input_handler_manager.h"
#include "content/renderer/input/main_thread_input_event_filter.h"
@@ -114,7 +116,6 @@
#include "content/renderer/media/video_capture_message_filter.h"
#include "content/renderer/net_info_helper.h"
#include "content/renderer/p2p/socket_dispatcher.h"
-#include "content/renderer/raster_worker_pool.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process_impl.h"
#include "content/renderer/render_view_impl.h"
@@ -130,8 +131,8 @@
#include "gpu/ipc/client/command_buffer_proxy_impl.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_channel_mojo.h"
#include "ipc/ipc_platform_file.h"
-#include "ipc/mojo/ipc_channel_mojo.h"
#include "media/base/audio_hardware_config.h"
#include "media/base/media.h"
#include "media/renderers/gpu_video_accelerator_factories.h"
@@ -151,7 +152,7 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
-#include "third_party/WebKit/public/web/WebMemoryPressureListener.h"
+#include "third_party/WebKit/public/web/WebMemoryCoordinator.h"
#include "third_party/WebKit/public/web/WebNetworkStateNotifier.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/web/WebScriptController.h"
@@ -164,8 +165,8 @@
#if defined(OS_ANDROID)
#include <cpu-features.h>
-#include "content/renderer/android/synchronous_compositor_external_begin_frame_source.h"
#include "content/renderer/android/synchronous_compositor_filter.h"
+#include "content/renderer/android/synchronous_compositor_output_surface.h"
#include "content/renderer/media/android/renderer_demuxer_android.h"
#include "content/renderer/media/android/stream_texture_factory.h"
#include "media/base/android/media_codec_util.h"
@@ -197,11 +198,17 @@
#include "v8/src/third_party/vtune/v8-vtune.h"
#endif
-#if defined(MOJO_SHELL_CLIENT)
+#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA)
+#include "components/mus/common/gpu_service.h"
#include "content/public/common/mojo_shell_connection.h"
+#include "content/renderer/mus/render_widget_mus_connection.h"
#include "content/renderer/mus/render_widget_window_tree_client_factory.h"
#endif
+#if defined(ENABLE_IPC_FUZZER)
+#include "content/common/external_ipc_dumper.h"
+#endif
+
using base::ThreadRestrictions;
using blink::WebDocument;
using blink::WebFrame;
@@ -236,6 +243,9 @@ const double kThrottledResourceRequestFlushPeriodS = 1. / 60.;
// allocation that exceeds this limit.
const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
+// Unique identifier for each output surface created.
+uint32_t g_next_output_surface_id = 1;
+
// Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
// incorrectly from the wrong thread.
base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> >
@@ -252,6 +262,20 @@ static_assert(static_cast<v8::MemoryPressureLevel>(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) ==
v8::MemoryPressureLevel::kCritical, "critical level not align");
+// WebMemoryPressureLevel should correspond to base::MemoryPressureListener.
+static_assert(static_cast<blink::WebMemoryPressureLevel>(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) ==
+ blink::WebMemoryPressureLevelNone,
+ "blink::WebMemoryPressureLevelNone not align");
+static_assert(static_cast<blink::WebMemoryPressureLevel>(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) ==
+ blink::WebMemoryPressureLevelModerate,
+ "blink::WebMemoryPressureLevelModerate not align");
+static_assert(static_cast<blink::WebMemoryPressureLevel>(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) ==
+ blink::WebMemoryPressureLevelCritical,
+ "blink::WebMemoryPressureLevelCritical not align");
+
class WebThreadForCompositor : public WebThreadImplForWorkerScheduler {
public:
explicit WebThreadForCompositor(base::Thread::Options options)
@@ -313,16 +337,16 @@ void NotifyTimezoneChangeOnThisThread() {
v8::Date::DateTimeConfigurationChangeNotification(isolate);
}
-class RenderFrameSetupImpl : public mojom::RenderFrameSetup {
+class FrameFactoryImpl : public mojom::FrameFactory {
public:
- explicit RenderFrameSetupImpl(
- mojo::InterfaceRequest<mojom::RenderFrameSetup> request)
+ explicit FrameFactoryImpl(mojom::FrameFactoryRequest request)
: routing_id_highmark_(-1), binding_(this, std::move(request)) {}
- void ExchangeInterfaceProviders(
- int32_t frame_routing_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services) override {
+ private:
+ // mojom::FrameFactory:
+ void CreateFrame(int32_t frame_routing_id,
+ mojom::FrameRequest frame_request,
+ mojom::FrameHostPtr frame_host) override {
// TODO(morrita): This is for investigating http://crbug.com/415059 and
// should be removed once it is fixed.
CHECK_LT(routing_id_highmark_, frame_routing_id);
@@ -333,28 +357,26 @@ class RenderFrameSetupImpl : public mojom::RenderFrameSetup {
// created due to a race between the message and a ViewMsg_New IPC that
// triggers creation of the RenderFrame we want.
if (!frame) {
- RenderThreadImpl::current()->RegisterPendingRenderFrameConnect(
- frame_routing_id, std::move(services), std::move(exposed_services));
+ RenderThreadImpl::current()->RegisterPendingFrameCreate(
+ frame_routing_id, std::move(frame_request), std::move(frame_host));
return;
}
- frame->BindServiceRegistry(std::move(services),
- std::move(exposed_services));
+ frame->Bind(std::move(frame_request), std::move(frame_host));
}
private:
int32_t routing_id_highmark_;
- mojo::StrongBinding<mojom::RenderFrameSetup> binding_;
+ mojo::StrongBinding<mojom::FrameFactory> binding_;
};
-void CreateRenderFrameSetup(
- mojo::InterfaceRequest<mojom::RenderFrameSetup> request) {
- new RenderFrameSetupImpl(std::move(request));
+void CreateFrameFactory(mojom::FrameFactoryRequest request) {
+ new FrameFactoryImpl(std::move(request));
}
void SetupEmbeddedWorkerOnWorkerThread(
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtrInfo exposed_services) {
+ shell::mojom::InterfaceProviderRequest request,
+ shell::mojom::InterfaceProviderPtrInfo remote_interfaces) {
ServiceWorkerContextClient* client =
ServiceWorkerContextClient::ThreadSpecificInstance();
// It is possible for client to be null if for some reason the worker died
@@ -362,8 +384,8 @@ void SetupEmbeddedWorkerOnWorkerThread(
// nothing and let mojo close the connection.
if (!client)
return;
- client->BindServiceRegistry(std::move(services),
- mojo::MakeProxy(std::move(exposed_services)));
+ client->BindInterfaceProviders(std::move(request),
+ mojo::MakeProxy(std::move(remote_interfaces)));
}
class EmbeddedWorkerSetupImpl : public mojom::EmbeddedWorkerSetup {
@@ -374,12 +396,12 @@ class EmbeddedWorkerSetupImpl : public mojom::EmbeddedWorkerSetup {
void ExchangeInterfaceProviders(
int32_t thread_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services) override {
+ shell::mojom::InterfaceProviderRequest request,
+ shell::mojom::InterfaceProviderPtr remote_interfaces) override {
WorkerThreadRegistry::Instance()->GetTaskRunnerFor(thread_id)->PostTask(
FROM_HERE,
- base::Bind(&SetupEmbeddedWorkerOnWorkerThread, base::Passed(&services),
- base::Passed(exposed_services.PassInterface())));
+ base::Bind(&SetupEmbeddedWorkerOnWorkerThread, base::Passed(&request),
+ base::Passed(remote_interfaces.PassInterface())));
}
private:
@@ -430,8 +452,7 @@ scoped_refptr<ContextProviderCommandBuffer> CreateOffscreenContext(
std::move(gpu_channel_host), stream_id, stream_priority,
gpu::kNullSurfaceHandle,
GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext"),
- gfx::PreferIntegratedGpu, automatic_flushes, support_locking, limits,
- attributes, nullptr, type));
+ automatic_flushes, support_locking, limits, attributes, nullptr, type));
}
} // namespace
@@ -582,9 +603,11 @@ RenderThreadImpl::RenderThreadImpl(
std::unique_ptr<scheduler::RendererScheduler> scheduler,
scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue)
: ChildThreadImpl(Options::Builder()
- .InBrowserProcess(params).UseMojoChannel(true).Build()),
+ .InBrowserProcess(params)
+ .UseMojoChannel(true)
+ .Build()),
renderer_scheduler_(std::move(scheduler)),
- raster_worker_pool_(new RasterWorkerPool()) {
+ categorized_worker_pool_(new CategorizedWorkerPool()) {
Init(resource_task_queue);
}
@@ -596,7 +619,7 @@ RenderThreadImpl::RenderThreadImpl(
: ChildThreadImpl(Options::Builder().UseMojoChannel(true).Build()),
renderer_scheduler_(std::move(scheduler)),
main_message_loop_(std::move(main_message_loop)),
- raster_worker_pool_(new RasterWorkerPool()) {
+ categorized_worker_pool_(new CategorizedWorkerPool()) {
scoped_refptr<base::SingleThreadTaskRunner> test_task_counter;
Init(test_task_counter);
}
@@ -609,7 +632,7 @@ void RenderThreadImpl::Init(
base::PlatformThread::CurrentId(),
kTraceEventRendererMainThreadSortIndex);
-#if defined(OS_MACOSX) || (defined(OS_ANDROID) && !defined(USE_AURA))
+#if defined(USE_EXTERNAL_POPUP_MENU)
// On Mac and Android Java UI, the select popups are rendered by the browser.
blink::WebView::setUseExternalPopupMenus(true);
#endif
@@ -627,7 +650,6 @@ void RenderThreadImpl::Init(
hidden_widget_count_ = 0;
idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
idle_notifications_to_skip_ = 0;
- layout_test_mode_ = false;
appcache_dispatcher_.reset(
new AppCacheDispatcher(Get(), new AppCacheFrontendImpl()));
@@ -648,7 +670,7 @@ void RenderThreadImpl::Init(
media_stream_center_ = NULL;
- blob_message_filter_ = new BlobMessageFilter();
+ blob_message_filter_ = new BlobMessageFilter(GetFileThreadMessageLoopProxy());
AddFilter(blob_message_filter_.get());
db_message_filter_ = new DBMessageFilter();
AddFilter(db_message_filter_.get());
@@ -690,9 +712,6 @@ void RenderThreadImpl::Init(
midi_message_filter_ = new MidiMessageFilter(GetIOMessageLoopProxy());
AddFilter(midi_message_filter_.get());
- bluetooth_message_filter_ = new BluetoothMessageFilter(thread_safe_sender());
- AddFilter(bluetooth_message_filter_->GetFilter());
-
AddFilter((new IndexedDBMessageFilter(thread_safe_sender()))->GetFilter());
AddFilter((new CacheStorageMessageFilter(thread_safe_sender()))->GetFilter());
@@ -708,6 +727,16 @@ void RenderThreadImpl::Init(
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
+#if defined(ENABLE_IPC_FUZZER)
+ if (command_line.HasSwitch(switches::kIpcDumpDirectory)) {
+ base::FilePath dump_directory =
+ command_line.GetSwitchValuePath(switches::kIpcDumpDirectory);
+ IPC::ChannelProxy::OutgoingMessageFilter* filter =
+ LoadExternalIPCDumper(dump_directory);
+ GetChannel()->set_outgoing_message_filter(filter);
+ }
+#endif
+
cc::SetClientNameForMetrics("Renderer");
is_threaded_animation_enabled_ =
@@ -800,7 +829,7 @@ void RenderThreadImpl::Init(
// image decode tasks.
are_image_decode_tasks_enabled_ = true;
- raster_worker_pool_->Start(num_raster_threads);
+ categorized_worker_pool_->Start(num_raster_threads);
// TODO(boliu): In single process, browser main loop should set up the
// discardable memory manager, and should skip this if kSingleProcess.
@@ -808,19 +837,22 @@ void RenderThreadImpl::Init(
base::DiscardableMemoryAllocator::SetInstance(
ChildThreadImpl::discardable_shared_memory_manager());
- service_registry()->AddService(base::Bind(CreateRenderFrameSetup));
- service_registry()->AddService(base::Bind(CreateEmbeddedWorkerSetup));
+ GetContentClient()->renderer()->ExposeInterfacesToBrowser(
+ GetInterfaceRegistry());
-#if defined(MOJO_SHELL_CLIENT)
+ GetInterfaceRegistry()->AddInterface(base::Bind(CreateFrameFactory));
+ GetInterfaceRegistry()->AddInterface(base::Bind(CreateEmbeddedWorkerSetup));
+
+#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA)
// We may not have a MojoShellConnection object in tests that directly
// instantiate a RenderThreadImpl.
- if (MojoShellConnection::Get() &&
+ if (MojoShellConnection::GetForProcess() &&
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseMusInRenderer))
CreateRenderWidgetWindowTreeClientFactory();
#endif
- service_registry()->ConnectToRemoteService(
+ GetRemoteInterfaces()->GetInterface(
mojo::GetProxy(&storage_partition_service_));
is_renderer_suspended_ = false;
@@ -896,7 +928,7 @@ void RenderThreadImpl::Shutdown() {
RemoveFilter(audio_message_filter_.get());
audio_message_filter_ = NULL;
- raster_worker_pool_->Shutdown();
+ categorized_worker_pool_->Shutdown();
main_input_callback_.Cancel();
input_handler_manager_.reset();
@@ -930,6 +962,7 @@ void RenderThreadImpl::Shutdown() {
// Shut down the message loop and the renderer scheduler before shutting down
// Blink. This prevents a scenario where a pending task in the message loop
// accesses Blink objects after Blink shuts down.
+ renderer_scheduler_->SetRAILModeObserver(nullptr);
renderer_scheduler_->Shutdown();
if (main_message_loop_)
main_message_loop_->RunUntilIdle();
@@ -1009,24 +1042,17 @@ RenderThreadImpl::GetIOMessageLoopProxy() {
void RenderThreadImpl::AddRoute(int32_t routing_id, IPC::Listener* listener) {
ChildThreadImpl::GetRouter()->AddRoute(routing_id, listener);
- PendingRenderFrameConnectMap::iterator it =
- pending_render_frame_connects_.find(routing_id);
- if (it == pending_render_frame_connects_.end())
+ auto it = pending_frame_creates_.find(routing_id);
+ if (it == pending_frame_creates_.end())
return;
RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(routing_id);
if (!frame)
return;
- scoped_refptr<PendingRenderFrameConnect> connection(it->second);
- shell::mojom::InterfaceProviderRequest services(
- std::move(connection->services()));
- shell::mojom::InterfaceProviderPtr exposed_services(
- std::move(connection->exposed_services()));
- exposed_services.set_connection_error_handler(mojo::Closure());
- pending_render_frame_connects_.erase(it);
-
- frame->BindServiceRegistry(std::move(services), std::move(exposed_services));
+ scoped_refptr<PendingFrameCreate> create(it->second);
+ frame->Bind(it->second->TakeFrameRequest(), it->second->TakeFrameHost());
+ pending_frame_creates_.erase(it);
}
void RenderThreadImpl::RemoveRoute(int32_t routing_id) {
@@ -1050,15 +1076,15 @@ void RenderThreadImpl::RemoveEmbeddedWorkerRoute(int32_t routing_id) {
}
}
-void RenderThreadImpl::RegisterPendingRenderFrameConnect(
+void RenderThreadImpl::RegisterPendingFrameCreate(
int routing_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services) {
- std::pair<PendingRenderFrameConnectMap::iterator, bool> result =
- pending_render_frame_connects_.insert(std::make_pair(
+ mojom::FrameRequest frame_request,
+ mojom::FrameHostPtr frame_host) {
+ std::pair<PendingFrameCreateMap::iterator, bool> result =
+ pending_frame_creates_.insert(std::make_pair(
routing_id,
- make_scoped_refptr(new PendingRenderFrameConnect(
- routing_id, std::move(services), std::move(exposed_services)))));
+ make_scoped_refptr(new PendingFrameCreate(
+ routing_id, std::move(frame_request), std::move(frame_host)))));
CHECK(result.second) << "Inserting a duplicate item.";
}
@@ -1105,7 +1131,6 @@ void RenderThreadImpl::InitializeCompositorThread() {
FROM_HERE,
base::Bind(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed), false));
- InputHandlerManagerClient* input_handler_manager_client = nullptr;
SynchronousInputHandlerProxyClient* synchronous_input_handler_proxy_client =
nullptr;
#if defined(OS_ANDROID)
@@ -1113,22 +1138,17 @@ void RenderThreadImpl::InitializeCompositorThread() {
sync_compositor_message_filter_ =
new SynchronousCompositorFilter(compositor_task_runner_);
AddFilter(sync_compositor_message_filter_.get());
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSyncInputForSyncCompositor)) {
- input_handler_manager_client = sync_compositor_message_filter_.get();
- }
synchronous_input_handler_proxy_client =
sync_compositor_message_filter_.get();
}
#endif
- if (!input_handler_manager_client) {
- scoped_refptr<InputEventFilter> compositor_input_event_filter(
- new InputEventFilter(main_input_callback_.callback(),
- main_thread_compositor_task_runner_,
- compositor_task_runner_));
- input_handler_manager_client = compositor_input_event_filter.get();
- input_event_filter_ = compositor_input_event_filter;
- }
+ scoped_refptr<InputEventFilter> compositor_input_event_filter(
+ new InputEventFilter(main_input_callback_.callback(),
+ main_thread_compositor_task_runner_,
+ compositor_task_runner_));
+ InputHandlerManagerClient* input_handler_manager_client =
+ compositor_input_event_filter.get();
+ input_event_filter_ = compositor_input_event_filter;
input_handler_manager_.reset(new InputHandlerManager(
compositor_task_runner_, input_handler_manager_client,
synchronous_input_handler_proxy_client, renderer_scheduler_.get()));
@@ -1150,12 +1170,13 @@ void RenderThreadImpl::InitializeWebKit(
blink_platform_impl_.reset(new RendererBlinkPlatformImpl(
renderer_scheduler_.get(),
- static_cast<ServiceRegistryImpl*>(service_registry())->GetWeakPtr()));
+ GetRemoteInterfaces()->GetWeakPtr()));
blink::initialize(blink_platform_impl_.get());
v8::Isolate* isolate = blink::mainThreadIsolate();
isolate->SetCreateHistogramFunction(CreateHistogram);
isolate->SetAddHistogramSampleFunction(AddHistogramSample);
+ renderer_scheduler_->SetRAILModeObserver(this);
main_thread_compositor_task_runner_ =
renderer_scheduler_->CompositorTaskRunner();
@@ -1184,6 +1205,9 @@ void RenderThreadImpl::InitializeWebKit(
resource_task_queue2);
resource_dispatcher()->SetMainThreadTaskRunner(resource_task_queue2);
+ websocket_message_filter()->SetLoadingTaskRunner(
+ renderer_scheduler_->LoadingTaskRunner());
+
if (!command_line.HasSwitch(switches::kDisableThreadedCompositing) &&
!command_line.HasSwitch(switches::kUseRemoteCompositing))
InitializeCompositorThread();
@@ -1266,6 +1290,10 @@ void RenderThreadImpl::RegisterSchemes() {
// chrome-devtools:
WebString devtools_scheme(base::ASCIIToUTF16(kChromeDevToolsScheme));
WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(devtools_scheme);
+
+ // view-source:
+ WebString view_source_scheme(base::ASCIIToUTF16(kViewSourceScheme));
+ WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(view_source_scheme);
}
void RenderThreadImpl::NotifyTimezoneChange() {
@@ -1499,7 +1527,7 @@ bool RenderThreadImpl::EnableStreamTextureCopy() {
AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
if (!audio_renderer_mixer_manager_) {
- audio_renderer_mixer_manager_.reset(new AudioRendererMixerManager());
+ audio_renderer_mixer_manager_ = AudioRendererMixerManager::Create();
}
return audio_renderer_mixer_manager_.get();
@@ -1531,11 +1559,6 @@ void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
#endif // OS_WIN
-ServiceRegistry* RenderThreadImpl::GetServiceRegistry() {
- DCHECK(service_registry());
- return service_registry();
-}
-
bool RenderThreadImpl::IsGpuRasterizationForced() {
return is_gpu_rasterization_forced_;
}
@@ -1600,12 +1623,6 @@ scheduler::RendererScheduler* RenderThreadImpl::GetRendererScheduler() {
std::unique_ptr<cc::BeginFrameSource>
RenderThreadImpl::CreateExternalBeginFrameSource(int routing_id) {
-#if defined(OS_ANDROID)
- if (sync_compositor_message_filter_) {
- return base::WrapUnique(new SynchronousCompositorExternalBeginFrameSource(
- routing_id, sync_compositor_message_filter_.get()));
- }
-#endif
return base::WrapUnique(new CompositorExternalBeginFrameSource(
compositor_message_filter_.get(), sync_message_filter(), routing_id));
}
@@ -1616,7 +1633,7 @@ RenderThreadImpl::GetImageSerializationProcessor() {
}
cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() {
- return raster_worker_pool_->GetTaskGraphRunner();
+ return categorized_worker_pool_->GetTaskGraphRunner();
}
bool RenderThreadImpl::AreImageDecodeTasksEnabled() {
@@ -1627,6 +1644,11 @@ bool RenderThreadImpl::IsThreadedAnimationEnabled() {
return is_threaded_animation_enabled_;
}
+void RenderThreadImpl::OnRAILModeChanged(v8::RAILMode rail_mode) {
+ blink::mainThreadIsolate()->SetRAILMode(rail_mode);
+ blink::setRAILModeOnWorkerThreadIsolates(rail_mode);
+}
+
bool RenderThreadImpl::IsMainThread() {
return !!current();
}
@@ -1789,6 +1811,123 @@ scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync(
return gpu_channel_;
}
+std::unique_ptr<cc::OutputSurface>
+RenderThreadImpl::CreateCompositorOutputSurface(
+ bool use_software,
+ int routing_id,
+ scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
+ const GURL& url) {
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kDisableGpuCompositing))
+ use_software = true;
+
+#if defined(MOJO_SHELL_CLIENT) && defined(USE_AURA)
+ auto shell_connection = MojoShellConnection::GetForProcess();
+ if (shell_connection && !use_software &&
+ command_line.HasSwitch(switches::kUseMusInRenderer)) {
+ mus::GpuService::Initialize(shell_connection->GetConnector());
+ RenderWidgetMusConnection* connection =
+ RenderWidgetMusConnection::GetOrCreate(routing_id);
+ return connection->CreateOutputSurface();
+ }
+#endif
+
+ uint32_t output_surface_id = g_next_output_surface_id++;
+
+ if (command_line.HasSwitch(switches::kEnableVulkan)) {
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider =
+ cc::VulkanInProcessContextProvider::Create();
+ if (vulkan_context_provider) {
+ DCHECK(!layout_test_mode());
+ return base::WrapUnique(new CompositorOutputSurface(
+ routing_id, output_surface_id, std::move(vulkan_context_provider),
+ std::move(frame_swap_message_queue)));
+ }
+ }
+
+ // Create a gpu process channel and verify we want to use GPU compositing
+ // before creating any context providers.
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host;
+ if (!use_software) {
+ gpu_channel_host = EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_RENDERER_VERIFY_GPU_COMPOSITING);
+ if (!gpu_channel_host) {
+ // Cause the compositor to wait and try again.
+ return nullptr;
+ }
+ // We may get a valid channel, but with a software renderer. In that case,
+ // disable GPU compositing.
+ if (gpu_channel_host->gpu_info().software_rendering)
+ use_software = true;
+ }
+
+ if (use_software) {
+ DCHECK(!layout_test_mode());
+ return base::WrapUnique(new CompositorOutputSurface(
+ routing_id, output_surface_id, nullptr, nullptr,
+ std::move(frame_swap_message_queue)));
+ }
+
+ scoped_refptr<ContextProviderCommandBuffer> worker_context_provider =
+ SharedCompositorWorkerContextProvider();
+ if (!worker_context_provider) {
+ // Cause the compositor to wait and try again.
+ return nullptr;
+ }
+
+ // The renderer compositor context doesn't do a lot of stuff, so we don't
+ // expect it to need a lot of space for commands or transfer. Raster and
+ // uploads happen on the worker context instead.
+ gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
+
+ // This is for an offscreen context for the compositor. So the default
+ // framebuffer doesn't need alpha, depth, stencil, antialiasing.
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = -1;
+ attributes.depth_size = 0;
+ attributes.stencil_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+ attributes.lose_context_when_out_of_memory = true;
+
+ constexpr bool automatic_flushes = false;
+ constexpr bool support_locking = false;
+
+ // The compositor context shares resources with the worker context unless
+ // the worker is async.
+ ContextProviderCommandBuffer* share_context = worker_context_provider.get();
+ if (IsAsyncWorkerContextEnabled())
+ share_context = nullptr;
+
+ scoped_refptr<ContextProviderCommandBuffer> context_provider(
+ new ContextProviderCommandBuffer(
+ gpu_channel_host, gpu::GPU_STREAM_DEFAULT,
+ gpu::GpuStreamPriority::NORMAL, gpu::kNullSurfaceHandle, url,
+ automatic_flushes, support_locking, limits, attributes, share_context,
+ command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT));
+
+ if (layout_test_deps_) {
+ return layout_test_deps_->CreateOutputSurface(
+ std::move(gpu_channel_host), std::move(context_provider),
+ std::move(worker_context_provider), this);
+ }
+
+#if defined(OS_ANDROID)
+ if (sync_compositor_message_filter_) {
+ return base::WrapUnique(new SynchronousCompositorOutputSurface(
+ std::move(context_provider), std::move(worker_context_provider),
+ routing_id, output_surface_id, sync_compositor_message_filter_.get(),
+ std::move(frame_swap_message_queue)));
+ }
+#endif
+
+ return base::WrapUnique(new CompositorOutputSurface(
+ routing_id, output_surface_id, std::move(context_provider),
+ std::move(worker_context_provider), std::move(frame_swap_message_queue)));
+}
+
blink::WebMediaStreamCenter* RenderThreadImpl::CreateMediaStreamCenter(
blink::WebMediaStreamCenterClient* client) {
#if defined(ENABLE_WEBRTC)
@@ -1906,7 +2045,7 @@ void RenderThreadImpl::OnMemoryPressure(
// Do not call into blink if it is not initialized.
if (blink_platform_impl_) {
- blink::WebMemoryPressureListener::onMemoryPressure(
+ blink::WebMemoryCoordinator::onMemoryPressure(
static_cast<blink::WebMemoryPressureLevel>(memory_pressure_level));
if (memory_pressure_level ==
@@ -1945,7 +2084,7 @@ RenderThreadImpl::GetMediaThreadTaskRunner() {
}
base::TaskRunner* RenderThreadImpl::GetWorkerTaskRunner() {
- return raster_worker_pool_.get();
+ return categorized_worker_pool_.get();
}
scoped_refptr<ContextProviderCommandBuffer>
@@ -2049,29 +2188,27 @@ void RenderThreadImpl::ReleaseFreeMemory() {
blink::decommitFreeableMemory();
}
-RenderThreadImpl::PendingRenderFrameConnect::PendingRenderFrameConnect(
+RenderThreadImpl::PendingFrameCreate::PendingFrameCreate(
int routing_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services)
+ mojom::FrameRequest frame_request,
+ mojom::FrameHostPtr frame_host)
: routing_id_(routing_id),
- services_(std::move(services)),
- exposed_services_(std::move(exposed_services)) {
- // The RenderFrame may be deleted before the ExchangeInterfaceProviders
- // message is received. In that case, the RenderFrameHost should close the
- // connection, which is detected by setting an error handler on
- // |exposed_services_|.
- exposed_services_.set_connection_error_handler(base::Bind(
- &RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError,
+ frame_request_(std::move(frame_request)),
+ frame_host_(std::move(frame_host)) {
+ // The RenderFrame may be deleted before the CreateFrame message is received.
+ // In that case, the RenderFrameHost should cancel the create, which is
+ // detected by setting an error handler on |frame_host_|.
+ frame_host_.set_connection_error_handler(base::Bind(
+ &RenderThreadImpl::PendingFrameCreate::OnConnectionError,
base::Unretained(this)));
}
-RenderThreadImpl::PendingRenderFrameConnect::~PendingRenderFrameConnect() {
+RenderThreadImpl::PendingFrameCreate::~PendingFrameCreate() {
}
-void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() {
+void RenderThreadImpl::PendingFrameCreate::OnConnectionError() {
size_t erased =
- RenderThreadImpl::current()->pending_render_frame_connects_.erase(
- routing_id_);
+ RenderThreadImpl::current()->pending_frame_creates_.erase(routing_id_);
DCHECK_EQ(1u, erased);
}
diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h
index 486efe0dbfe..1f26f30d512 100644
--- a/chromium/content/renderer/render_thread_impl.h
+++ b/chromium/content/renderer/render_thread_impl.h
@@ -22,13 +22,16 @@
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
+#include "components/scheduler/renderer/renderer_scheduler.h"
#include "content/child/child_thread_impl.h"
#include "content/common/content_export.h"
+#include "content/common/frame.mojom.h"
#include "content/common/frame_replication_state.h"
#include "content/common/gpu_process_launch_causes.h"
#include "content/common/storage_partition_service.mojom.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/gpu/compositor_dependencies.h"
+#include "content/renderer/layout_test_dependencies.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "net/base/network_change_notifier.h"
#include "third_party/WebKit/public/platform/WebConnectionType.h"
@@ -59,6 +62,7 @@ class Thread;
namespace cc {
class ContextProvider;
class ImageSerializationProcessor;
+class OutputSurface;
class TaskGraphRunner;
}
@@ -76,7 +80,6 @@ class GpuVideoAcceleratorFactories;
}
namespace scheduler {
-class RendererScheduler;
class WebThreadBase;
}
@@ -92,7 +95,6 @@ class AudioInputMessageFilter;
class AudioMessageFilter;
class AudioRendererMixerManager;
class BlobMessageFilter;
-class BluetoothMessageFilter;
class BrowserPluginManager;
class CacheStorageDispatcher;
class CompositorForwardingMessageFilter;
@@ -101,6 +103,7 @@ class DBMessageFilter;
class DevToolsAgentFilter;
class DomStorageDispatcher;
class EmbeddedWorkerDispatcher;
+class FrameSwapMessageQueue;
class IndexedDBDispatcher;
class InputHandlerManager;
class MediaStreamCenter;
@@ -110,7 +113,7 @@ class NetInfoDispatcher;
class P2PSocketDispatcher;
class PeerConnectionDependencyFactory;
class PeerConnectionTracker;
-class RasterWorkerPool;
+class CategorizedWorkerPool;
class RenderThreadObserver;
class RendererBlinkPlatformImpl;
class RendererDemuxerAndroid;
@@ -144,6 +147,7 @@ class CONTENT_EXPORT RenderThreadImpl
: public RenderThread,
public ChildThreadImpl,
public gpu::GpuChannelHostFactory,
+ public scheduler::RendererScheduler::RAILModeObserver,
NON_EXPORTED_BASE(public CompositorDependencies) {
public:
static RenderThreadImpl* Create(const InProcessChildThreadParams& params);
@@ -191,7 +195,6 @@ class CONTENT_EXPORT RenderThreadImpl
int PostTaskToAllWebWorkers(const base::Closure& closure) override;
bool ResolveProxy(const GURL& url, std::string* proxy_list) override;
base::WaitableEvent* GetShutdownEvent() override;
- ServiceRegistry* GetServiceRegistry() override;
// CompositorDependencies implementation.
bool IsGpuRasterizationForced() override;
@@ -218,20 +221,28 @@ class CONTENT_EXPORT RenderThreadImpl
bool AreImageDecodeTasksEnabled() override;
bool IsThreadedAnimationEnabled() override;
+ // scheduler::RendererScheduler::RAILModeObserver implementation.
+ void OnRAILModeChanged(v8::RAILMode rail_mode) override;
+
// Synchronously establish a channel to the GPU plugin if not previously
// established or if it has been lost (for example if the GPU plugin crashed).
// If there is a pending asynchronous request, it will be completed by the
// time this routine returns.
scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(CauseForGpuLaunch);
+ std::unique_ptr<cc::OutputSurface> CreateCompositorOutputSurface(
+ bool use_software,
+ int routing_id,
+ scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
+ const GURL& url);
+
// True if we are running layout tests. This currently disables forwarding
// various status messages to the console, skips network error pages, and
// short circuits size update and focus events.
- bool layout_test_mode() const {
- return layout_test_mode_;
- }
- void set_layout_test_mode(bool layout_test_mode) {
- layout_test_mode_ = layout_test_mode;
+ bool layout_test_mode() const { return !!layout_test_deps_; }
+ void set_layout_test_dependencies(
+ std::unique_ptr<LayoutTestDependencies> deps) {
+ layout_test_deps_ = std::move(deps);
}
RendererBlinkPlatformImpl* blink_platform_impl() const {
@@ -437,10 +448,9 @@ class CONTENT_EXPORT RenderThreadImpl
void AddEmbeddedWorkerRoute(int32_t routing_id, IPC::Listener* listener);
void RemoveEmbeddedWorkerRoute(int32_t routing_id);
- void RegisterPendingRenderFrameConnect(
- int routing_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services);
+ void RegisterPendingFrameCreate(int routing_id,
+ mojom::FrameRequest frame,
+ mojom::FrameHostPtr host);
mojom::StoragePartitionService* GetStoragePartitionService();
@@ -576,8 +586,8 @@ class CONTENT_EXPORT RenderThreadImpl
bool webkit_shared_timer_suspended_;
- // The following flag is used to control layout test specific behavior.
- bool layout_test_mode_;
+ // Used to control layout test specific behavior.
+ std::unique_ptr<LayoutTestDependencies> layout_test_deps_;
// Timer that periodically calls IdleHandler.
base::RepeatingTimer idle_timer_;
@@ -614,7 +624,7 @@ class CONTENT_EXPORT RenderThreadImpl
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
// Pool of workers used for raster operations (e.g., tile rasterization).
- scoped_refptr<RasterWorkerPool> raster_worker_pool_;
+ scoped_refptr<CategorizedWorkerPool> categorized_worker_pool_;
base::CancelableCallback<void(const IPC::Message&)> main_input_callback_;
scoped_refptr<IPC::MessageFilter> input_event_filter_;
@@ -626,8 +636,6 @@ class CONTENT_EXPORT RenderThreadImpl
scoped_refptr<StreamTextureFactory> stream_texture_factory_;
#endif
- scoped_refptr<BluetoothMessageFilter> bluetooth_message_filter_;
-
scoped_refptr<ContextProviderCommandBuffer> shared_main_thread_contexts_;
base::ObserverList<RenderThreadObserver> observers_;
@@ -666,36 +674,34 @@ class CONTENT_EXPORT RenderThreadImpl
bool are_image_decode_tasks_enabled_;
bool is_threaded_animation_enabled_;
- class PendingRenderFrameConnect
- : public base::RefCounted<PendingRenderFrameConnect> {
+ class PendingFrameCreate : public base::RefCounted<PendingFrameCreate> {
public:
- PendingRenderFrameConnect(
- int routing_id,
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services);
-
- shell::mojom::InterfaceProviderRequest& services() { return services_; }
-
- shell::mojom::InterfaceProviderPtr& exposed_services() {
- return exposed_services_;
+ PendingFrameCreate(int routing_id,
+ mojom::FrameRequest frame_request,
+ mojom::FrameHostPtr frame_host);
+
+ mojom::FrameRequest TakeFrameRequest() { return std::move(frame_request_); }
+ mojom::FrameHostPtr TakeFrameHost() {
+ frame_host_.set_connection_error_handler(base::Closure());
+ return std::move(frame_host_);
}
private:
- friend class base::RefCounted<PendingRenderFrameConnect>;
+ friend class base::RefCounted<PendingFrameCreate>;
- ~PendingRenderFrameConnect();
+ ~PendingFrameCreate();
// Mojo error handler.
void OnConnectionError();
int routing_id_;
- shell::mojom::InterfaceProviderRequest services_;
- shell::mojom::InterfaceProviderPtr exposed_services_;
+ mojom::FrameRequest frame_request_;
+ mojom::FrameHostPtr frame_host_;
};
- typedef std::map<int, scoped_refptr<PendingRenderFrameConnect>>
- PendingRenderFrameConnectMap;
- PendingRenderFrameConnectMap pending_render_frame_connects_;
+ using PendingFrameCreateMap =
+ std::map<int, scoped_refptr<PendingFrameCreate>>;
+ PendingFrameCreateMap pending_frame_creates_;
mojom::StoragePartitionServicePtr storage_partition_service_;
diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc
index 98c0ad33f9c..57747020cd7 100644
--- a/chromium/content/renderer/render_view_browsertest.cc
+++ b/chromium/content/renderer/render_view_browsertest.cc
@@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <tuple>
#include "base/bind.h"
#include "base/callback.h"
@@ -45,7 +46,7 @@
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
-#include "content/renderer/accessibility/renderer_accessibility.h"
+#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/history_controller.h"
@@ -546,54 +547,6 @@ TEST_F(RenderViewImplTest, RenderFrameClearedAfterClose) {
new_view->Release();
}
-TEST_F(RenderViewImplTest, SaveImageFromDataURL) {
- const IPC::Message* msg1 = render_thread_->sink().GetFirstMessageMatching(
- ViewHostMsg_SaveImageFromDataURL::ID);
- EXPECT_FALSE(msg1);
- render_thread_->sink().ClearMessages();
-
- const std::string image_data_url =
- "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
-
- view()->saveImageFromDataURL(WebString::fromUTF8(image_data_url));
- ProcessPendingMessages();
- const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching(
- ViewHostMsg_SaveImageFromDataURL::ID);
- EXPECT_TRUE(msg2);
-
- ViewHostMsg_SaveImageFromDataURL::Param param1;
- ViewHostMsg_SaveImageFromDataURL::Read(msg2, &param1);
- EXPECT_EQ(base::get<2>(param1).length(), image_data_url.length());
- EXPECT_EQ(base::get<2>(param1), image_data_url);
-
- ProcessPendingMessages();
- render_thread_->sink().ClearMessages();
-
- const std::string large_data_url(1024 * 1024 * 20 - 1, 'd');
-
- view()->saveImageFromDataURL(WebString::fromUTF8(large_data_url));
- ProcessPendingMessages();
- const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching(
- ViewHostMsg_SaveImageFromDataURL::ID);
- EXPECT_TRUE(msg3);
-
- ViewHostMsg_SaveImageFromDataURL::Param param2;
- ViewHostMsg_SaveImageFromDataURL::Read(msg3, &param2);
- EXPECT_EQ(base::get<2>(param2).length(), large_data_url.length());
- EXPECT_EQ(base::get<2>(param2), large_data_url);
-
- ProcessPendingMessages();
- render_thread_->sink().ClearMessages();
-
- const std::string exceeded_data_url(1024 * 1024 * 20 + 1, 'd');
-
- view()->saveImageFromDataURL(WebString::fromUTF8(exceeded_data_url));
- ProcessPendingMessages();
- const IPC::Message* msg4 = render_thread_->sink().GetFirstMessageMatching(
- ViewHostMsg_SaveImageFromDataURL::ID);
- EXPECT_FALSE(msg4);
-}
-
// Test that we get form state change notifications when input fields change.
TEST_F(RenderViewImplTest, OnNavStateChanged) {
view()->set_send_content_state_immediately(true);
@@ -633,11 +586,11 @@ TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
request_params.page_id = -1;
// Set up post data.
- const unsigned char* raw_data = reinterpret_cast<const unsigned char*>(
- "post \0\ndata");
- const unsigned int length = 11;
- const std::vector<unsigned char> post_data(raw_data, raw_data + length);
- start_params.browser_initiated_post_data = post_data;
+ const char raw_data[] = "post \0\ndata";
+ const size_t length = arraysize(raw_data);
+ scoped_refptr<ResourceRequestBodyImpl> post_data(new ResourceRequestBodyImpl);
+ post_data->AppendBytes(raw_data, length);
+ common_params.post_data = post_data;
frame()->Navigate(common_params, start_params, request_params);
ProcessPendingMessages();
@@ -650,12 +603,12 @@ TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
FrameHostMsg_DidCommitProvisionalLoad::Param host_nav_params;
FrameHostMsg_DidCommitProvisionalLoad::Read(frame_navigate_msg,
&host_nav_params);
- EXPECT_EQ("POST", base::get<0>(host_nav_params).method);
+ EXPECT_EQ("POST", std::get<0>(host_nav_params).method);
// Check post data sent to browser matches
- EXPECT_TRUE(base::get<0>(host_nav_params).page_state.IsValid());
+ EXPECT_TRUE(std::get<0>(host_nav_params).page_state.IsValid());
std::unique_ptr<HistoryEntry> entry =
- PageStateToHistoryEntry(base::get<0>(host_nav_params).page_state);
+ PageStateToHistoryEntry(std::get<0>(host_nav_params).page_state);
blink::WebHTTPBody body = entry->root().httpBody();
blink::WebHTTPBody::Element element;
bool successful = body.elementAt(0, element);
@@ -697,7 +650,7 @@ TEST_F(RenderViewImplTest, OnBrowserNavigationUpdatePageID) {
FrameHostMsg_DidCommitProvisionalLoad::Param host_nav_params;
FrameHostMsg_DidCommitProvisionalLoad::Read(frame_navigate_msg,
&host_nav_params);
- EXPECT_TRUE(base::get<0>(host_nav_params).page_state.IsValid());
+ EXPECT_TRUE(std::get<0>(host_nav_params).page_state.IsValid());
const IPC::Message* frame_page_id_msg =
render_thread_->sink().GetUniqueMessageMatching(
@@ -707,7 +660,7 @@ TEST_F(RenderViewImplTest, OnBrowserNavigationUpdatePageID) {
FrameHostMsg_DidAssignPageId::Param host_page_id_params;
FrameHostMsg_DidAssignPageId::Read(frame_page_id_msg, &host_page_id_params);
- EXPECT_EQ(base::get<0>(host_page_id_params), view_page_id());
+ EXPECT_EQ(std::get<0>(host_page_id_params), view_page_id());
}
#if defined(OS_ANDROID)
@@ -734,7 +687,7 @@ TEST_F(RenderViewImplTest, OnNavigationLoadDataWithBaseURL) {
// Check post data sent to browser matches.
FrameHostMsg_UpdateTitle::Param title_params;
EXPECT_TRUE(FrameHostMsg_UpdateTitle::Read(frame_title_msg, &title_params));
- EXPECT_EQ(base::ASCIIToUTF16("Data page"), base::get<0>(title_params));
+ EXPECT_EQ(base::ASCIIToUTF16("Data page"), std::get<0>(title_params));
}
#endif
@@ -1044,8 +997,8 @@ TEST_F(RenderViewImplTest, DISABLED_LastCommittedUpdateState) {
ASSERT_TRUE(msg_A);
ViewHostMsg_UpdateState::Param param;
ViewHostMsg_UpdateState::Read(msg_A, &param);
- int page_id_A = base::get<0>(param);
- PageState state_A = base::get<1>(param);
+ int page_id_A = std::get<0>(param);
+ PageState state_A = std::get<1>(param);
EXPECT_EQ(1, page_id_A);
render_thread_->sink().ClearMessages();
@@ -1058,8 +1011,8 @@ TEST_F(RenderViewImplTest, DISABLED_LastCommittedUpdateState) {
ViewHostMsg_UpdateState::ID);
ASSERT_TRUE(msg_B);
ViewHostMsg_UpdateState::Read(msg_B, &param);
- int page_id_B = base::get<0>(param);
- PageState state_B = base::get<1>(param);
+ int page_id_B = std::get<0>(param);
+ PageState state_B = std::get<1>(param);
EXPECT_EQ(2, page_id_B);
EXPECT_NE(state_A, state_B);
render_thread_->sink().ClearMessages();
@@ -1073,8 +1026,8 @@ TEST_F(RenderViewImplTest, DISABLED_LastCommittedUpdateState) {
ViewHostMsg_UpdateState::ID);
ASSERT_TRUE(msg_C);
ViewHostMsg_UpdateState::Read(msg_C, &param);
- int page_id_C = base::get<0>(param);
- PageState state_C = base::get<1>(param);
+ int page_id_C = std::get<0>(param);
+ PageState state_C = std::get<1>(param);
EXPECT_EQ(3, page_id_C);
EXPECT_NE(state_B, state_C);
render_thread_->sink().ClearMessages();
@@ -1128,8 +1081,8 @@ TEST_F(RenderViewImplTest, DISABLED_LastCommittedUpdateState) {
ViewHostMsg_UpdateState::ID);
ASSERT_TRUE(msg);
ViewHostMsg_UpdateState::Read(msg, &param);
- int page_id = base::get<0>(param);
- PageState state = base::get<1>(param);
+ int page_id = std::get<0>(param);
+ PageState state = std::get<1>(param);
EXPECT_EQ(page_id_C, page_id);
EXPECT_NE(state_A, state);
EXPECT_NE(state_B, state);
@@ -1202,7 +1155,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Param params;
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
- TextInputState p = base::get<0>(params);
+ TextInputState p = std::get<0>(params);
ui::TextInputType type = p.type;
ui::TextInputMode input_mode = p.mode;
bool can_compose_inline = p.can_compose_inline;
@@ -1222,7 +1175,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
EXPECT_TRUE(msg != NULL);
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
- p = base::get<0>(params);
+ p = std::get<0>(params);
type = p.type;
input_mode = p.mode;
EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, type);
@@ -1247,7 +1200,7 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
EXPECT_TRUE(msg != NULL);
EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
ViewHostMsg_TextInputStateChanged::Read(msg, &params);
- p = base::get<0>(params);
+ p = std::get<0>(params);
type = p.type;
input_mode = p.mode;
EXPECT_EQ(test_case->expected_mode, input_mode);
@@ -2007,7 +1960,7 @@ TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
ViewHostMsg_FocusedNodeChanged::Param params;
ViewHostMsg_FocusedNodeChanged::Read(msg1, &params);
- EXPECT_TRUE(base::get<0>(params));
+ EXPECT_TRUE(std::get<0>(params));
render_thread_->sink().ClearMessages();
ExecuteJavaScriptForTests("document.getElementById('test2').focus();");
@@ -2015,7 +1968,7 @@ TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
ViewHostMsg_FocusedNodeChanged::ID);
EXPECT_TRUE(msg2);
ViewHostMsg_FocusedNodeChanged::Read(msg2, &params);
- EXPECT_TRUE(base::get<0>(params));
+ EXPECT_TRUE(std::get<0>(params));
render_thread_->sink().ClearMessages();
view()->webview()->clearFocusedElement();
@@ -2023,7 +1976,7 @@ TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
ViewHostMsg_FocusedNodeChanged::ID);
EXPECT_TRUE(msg3);
ViewHostMsg_FocusedNodeChanged::Read(msg3, &params);
- EXPECT_FALSE(base::get<0>(params));
+ EXPECT_FALSE(std::get<0>(params));
render_thread_->sink().ClearMessages();
}
@@ -2071,19 +2024,19 @@ TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) {
TEST_F(RenderViewImplTest, OnSetAccessibilityMode) {
ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode());
- ASSERT_EQ((RendererAccessibility*) NULL, frame()->renderer_accessibility());
+ ASSERT_FALSE(frame()->render_accessibility());
frame()->SetAccessibilityMode(AccessibilityModeTreeOnly);
ASSERT_EQ(AccessibilityModeTreeOnly, frame()->accessibility_mode());
- ASSERT_NE((RendererAccessibility*) NULL, frame()->renderer_accessibility());
+ ASSERT_TRUE(frame()->render_accessibility());
frame()->SetAccessibilityMode(AccessibilityModeOff);
ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode());
- ASSERT_EQ((RendererAccessibility*) NULL, frame()->renderer_accessibility());
+ ASSERT_FALSE(frame()->render_accessibility());
frame()->SetAccessibilityMode(AccessibilityModeComplete);
ASSERT_EQ(AccessibilityModeComplete, frame()->accessibility_mode());
- ASSERT_NE((RendererAccessibility*) NULL, frame()->renderer_accessibility());
+ ASSERT_TRUE(frame()->render_accessibility());
}
// Sanity check for the Navigation Timing API |navigationStart| override. We
@@ -2123,7 +2076,7 @@ TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) {
FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params;
FrameHostMsg_DidStartProvisionalLoad::Read(frame_navigate_msg,
&host_nav_params);
- base::TimeTicks transmitted_start = base::get<1>(host_nav_params);
+ base::TimeTicks transmitted_start = std::get<1>(host_nav_params);
EXPECT_FALSE(transmitted_start.is_null());
EXPECT_LT(lower_bound_navigation_start, transmitted_start);
}
@@ -2147,7 +2100,7 @@ TEST_F(RenderViewImplTest, BrowserNavigationStartNotUsedForReload) {
FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
// The true timestamp is later than the browser initiated one.
- EXPECT_PRED2(TimeTicksGT, base::get<1>(host_nav_params),
+ EXPECT_PRED2(TimeTicksGT, std::get<1>(host_nav_params),
common_params.navigation_start);
}
@@ -2169,7 +2122,7 @@ TEST_F(RenderViewImplTest, BrowserNavigationStartNotUsedForHistoryNavigation) {
StartNavigationParams(), RequestNavigationParams());
FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_PRED2(TimeTicksGT, base::get<1>(host_nav_params),
+ EXPECT_PRED2(TimeTicksGT, std::get<1>(host_nav_params),
common_params_back.navigation_start);
render_thread_->sink().ClearMessages();
@@ -2182,7 +2135,7 @@ TEST_F(RenderViewImplTest, BrowserNavigationStartNotUsedForHistoryNavigation) {
StartNavigationParams(), RequestNavigationParams());
FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params2 =
ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_PRED2(TimeTicksGT, base::get<1>(host_nav_params2),
+ EXPECT_PRED2(TimeTicksGT, std::get<1>(host_nav_params2),
common_params_forward.navigation_start);
}
@@ -2197,7 +2150,7 @@ TEST_F(RenderViewImplTest, BrowserNavigationStartSuccessfullyTransmitted) {
FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_EQ(base::get<1>(host_nav_params), common_params.navigation_start);
+ EXPECT_EQ(std::get<1>(host_nav_params), common_params.navigation_start);
}
TEST_F(RenderViewImplTest, PreferredSizeZoomed) {
diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc
index c6c6a4991ce..be61076b8df 100644
--- a/chromium/content/renderer/render_view_impl.cc
+++ b/chromium/content/renderer/render_view_impl.cc
@@ -19,17 +19,20 @@
#include "base/i18n/rtl.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
+#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/process/kill.h"
#include "base/process/process.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -42,15 +45,12 @@
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
-#include "content/common/database_messages.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/common/drag_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_replication_state.h"
-#include "content/common/input/input_event_utils.h"
#include "content/common/input_messages.h"
#include "content/common/page_messages.h"
-#include "content/common/pepper_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/ssl_status_serialization.h"
#include "content/common/view_messages.h"
@@ -60,8 +60,6 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/favicon_url.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/page_importance_signals.h"
#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
@@ -92,7 +90,6 @@
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
-#include "content/renderer/render_view_mouse_lock_dispatcher.h"
#include "content/renderer/render_widget_fullscreen_pepper.h"
#include "content/renderer/renderer_webapplicationcachehost_impl.h"
#include "content/renderer/resizing_mode_selector.h"
@@ -392,39 +389,55 @@ static void ConvertToFaviconSizes(
///////////////////////////////////////////////////////////////////////////////
-struct RenderViewImpl::PendingFileChooser {
- PendingFileChooser(const FileChooserParams& p, WebFileChooserCompletion* c)
- : params(p),
- completion(c) {
- }
- FileChooserParams params;
- WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
-};
-
namespace {
-class WebWidgetLockTarget : public MouseLockDispatcher::LockTarget {
- public:
- explicit WebWidgetLockTarget(blink::WebWidget* webwidget)
- : webwidget_(webwidget) {}
-
- void OnLockMouseACK(bool succeeded) override {
- if (succeeded)
- webwidget_->didAcquirePointerLock();
- else
- webwidget_->didNotAcquirePointerLock();
- }
+WebDragData DropMetaDataToWebDragData(
+ const std::vector<DropData::Metadata>& drop_meta_data) {
+ std::vector<WebDragData::Item> item_list;
+ for (const auto& meta_data_item : drop_meta_data) {
+ if (meta_data_item.kind == DropData::Kind::STRING) {
+ WebDragData::Item item;
+ item.storageType = WebDragData::Item::StorageTypeString;
+ item.stringType = meta_data_item.mime_type;
+ // Have to pass a dummy URL here instead of an empty URL because the
+ // DropData received by browser_plugins goes through a round trip:
+ // DropData::MetaData --> WebDragData-->DropData. In the end, DropData
+ // will contain an empty URL (which means no URL is dragged) if the URL in
+ // WebDragData is empty.
+ if (base::EqualsASCII(meta_data_item.mime_type,
+ ui::Clipboard::kMimeTypeURIList)) {
+ item.stringData = WebString::fromUTF8("about:dragdrop-placeholder");
+ }
+ item_list.push_back(item);
+ continue;
+ }
- void OnMouseLockLost() override { webwidget_->didLosePointerLock(); }
+ // TODO(hush): crbug.com/584789. Blink needs to support creating a file with
+ // just the mimetype. This is needed to drag files to WebView on Android
+ // platform.
+ if ((meta_data_item.kind == DropData::Kind::FILENAME) &&
+ !meta_data_item.filename.empty()) {
+ WebDragData::Item item;
+ item.storageType = WebDragData::Item::StorageTypeFilename;
+ item.filenameData = meta_data_item.filename.AsUTF16Unsafe();
+ item_list.push_back(item);
+ continue;
+ }
- bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
- // The WebWidget handles mouse lock in WebKit's handleInputEvent().
- return false;
+ if (meta_data_item.kind == DropData::Kind::FILESYSTEMFILE) {
+ WebDragData::Item item;
+ item.storageType = WebDragData::Item::StorageTypeFileSystemFile;
+ item.fileSystemURL = meta_data_item.file_system_url;
+ item_list.push_back(item);
+ continue;
+ }
}
- private:
- blink::WebWidget* webwidget_;
-};
+ WebDragData result;
+ result.initialize();
+ result.setItems(item_list);
+ return result;
+}
WebDragData DropDataToWebDragData(const DropData& drop_data) {
std::vector<WebDragData::Item> item_list;
@@ -442,8 +455,6 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) {
item_list.push_back(item);
}
- // TODO(dcheng): Do we need to distinguish between null and empty URLs? Is it
- // meaningful to write an empty URL to the clipboard?
if (!drop_data.url.is_empty()) {
WebDragData::Item item;
item.storageType = WebDragData::Item::StorageTypeString;
@@ -606,14 +617,19 @@ GetV8CacheStrategiesForCacheStorage() {
*base::CommandLine::ForCurrentProcess();
std::string v8_cache_strategies = command_line.GetSwitchValueASCII(
switches::kV8CacheStrategiesForCacheStorage);
- if (v8_cache_strategies.empty())
+ if (v8_cache_strategies.empty()) {
v8_cache_strategies =
base::FieldTrialList::FindFullName("V8CacheStrategiesForCacheStorage");
- if (v8_cache_strategies == "none") {
+ }
+
+ if (base::StartsWith(v8_cache_strategies, "none",
+ base::CompareCase::SENSITIVE)) {
return WebSettings::V8CacheStrategiesForCacheStorage::None;
- } else if (v8_cache_strategies == "normal") {
+ } else if (base::StartsWith(v8_cache_strategies, "normal",
+ base::CompareCase::SENSITIVE)) {
return WebSettings::V8CacheStrategiesForCacheStorage::Normal;
- } else if (v8_cache_strategies == "aggressive") {
+ } else if (base::StartsWith(v8_cache_strategies, "aggressive",
+ base::CompareCase::SENSITIVE)) {
return WebSettings::V8CacheStrategiesForCacheStorage::Aggressive;
} else {
return WebSettings::V8CacheStrategiesForCacheStorage::Default;
@@ -654,7 +670,6 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
main_render_frame_(nullptr),
frame_widget_(nullptr),
speech_recognition_dispatcher_(NULL),
- mouse_lock_dispatcher_(NULL),
#if defined(OS_ANDROID)
expected_content_intent_id_(0),
#endif
@@ -679,9 +694,10 @@ void RenderViewImpl::Initialize(const ViewMsg_New_Params& params,
// Ensure we start with a valid next_page_id_ from the browser.
DCHECK_GE(next_page_id_, 0);
- webview_ = WebView::create(this);
- webwidget_ = webview_->widget();
- webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_));
+ webview_ =
+ WebView::create(this, is_hidden() ? blink::WebPageVisibilityStateHidden
+ : blink::WebPageVisibilityStateVisible);
+ RenderWidget::DoInit(MSG_ROUTING_NONE, webview_->widget(), nullptr);
g_view_map.Get().insert(std::make_pair(webview(), this));
g_routing_id_view_map.Get().insert(std::make_pair(GetRoutingID(), this));
@@ -709,6 +725,7 @@ void RenderViewImpl::Initialize(const ViewMsg_New_Params& params,
command_line.HasSwitch(switches::kRootLayerScrolls));
webview()->setShowFPSCounter(
command_line.HasSwitch(cc::switches::kShowFPSCounter));
+ webview()->setDeviceColorProfile(params.image_decode_color_profile);
ApplyWebPreferencesInternal(webkit_preferences_, webview(), compositor_deps_);
@@ -767,17 +784,6 @@ void RenderViewImpl::Initialize(const ViewMsg_New_Params& params,
content_detectors_.push_back(base::WrapUnique(new EmailDetector()));
#endif
- RenderThread::Get()->AddRoute(GetRoutingID(), this);
- // Take a reference on behalf of the RenderThread. This will be balanced
- // when we receive ViewMsg_Close in the RenderWidget (which RenderView
- // inherits from).
- AddRef();
- if (RenderThreadImpl::current()) {
- RenderThreadImpl::current()->WidgetCreated();
- if (is_hidden_)
- RenderThreadImpl::current()->WidgetHidden();
- }
-
// If this is a popup, we must wait for the CreatingNew_ACK message before
// completing initialization. Otherwise, we can finish it now.
if (opener_id_ == MSG_ROUTING_NONE)
@@ -809,10 +815,6 @@ void RenderViewImpl::Initialize(const ViewMsg_New_Params& params,
new TextInputClientObserver(this);
#endif // defined(OS_MACOSX)
- // The next group of objects all implement RenderViewObserver, so are deleted
- // along with the RenderView automatically.
- mouse_lock_dispatcher_ = new RenderViewMouseLockDispatcher(this);
-
// We don't use HistoryController in OOPIF-enabled modes.
if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
history_controller_.reset(new HistoryController(this));
@@ -845,18 +847,9 @@ RenderViewImpl::~RenderViewImpl() {
++it)
delete it->second;
- // If file chooser is still waiting for answer, dispatch empty answer.
- while (!file_chooser_completions_.empty()) {
- if (file_chooser_completions_.front()->completion) {
- file_chooser_completions_.front()->completion->didChooseFile(
- WebVector<WebString>());
- }
- file_chooser_completions_.pop_front();
- }
-
#if defined(OS_ANDROID)
- // The date/time picker client is both a scoped_ptr member of this class and
- // a RenderViewObserver. Reset it to prevent double deletion.
+ // The date/time picker client is both a std::unique_ptr member of this class
+ // and a RenderViewObserver. Reset it to prevent double deletion.
date_time_picker_client_.reset();
#endif
@@ -1123,8 +1116,12 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
prefs.report_screen_size_in_physical_pixels_quirk);
settings->setShouldReuseGlobalForUnownedMainFrame(
prefs.resue_global_for_unowned_main_frame);
+ settings->setProgressBarCompletion(
+ static_cast<WebSettings::ProgressBarCompletion>(
+ prefs.progress_bar_completion));
settings->setPreferHiddenVolumeControls(true);
- settings->setShrinksViewportContentToFit(true);
+ WebRuntimeFeatures::enableAutoplayMutedVideos(
+ prefs.autoplay_muted_videos_enabled);
#endif
settings->setAutoplayExperimentMode(
@@ -1132,6 +1129,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->setViewportEnabled(prefs.viewport_enabled);
settings->setViewportMetaEnabled(prefs.viewport_meta_enabled);
+ settings->setShrinksViewportContentToFit(
+ prefs.shrinks_viewport_contents_to_fit);
settings->setViewportStyle(
static_cast<blink::WebViewportStyle>(prefs.viewport_style));
@@ -1144,13 +1143,13 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->setUseSolidColorScrollbars(prefs.use_solid_color_scrollbars);
settings->setShowContextMenuOnMouseUp(prefs.context_menu_on_mouse_up);
+ settings->setAlwaysShowContextMenuOnTouch(
+ prefs.always_show_context_menu_on_touch);
#if defined(OS_MACOSX)
settings->setDoubleTapToZoomEnabled(true);
web_view->setMaximumLegibleScale(prefs.default_maximum_page_scale_factor);
#endif
-
- settings->setWheelGesturesEnabled(UseGestureBasedWheelScrolling());
}
/*static*/
@@ -1288,8 +1287,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
OnScrollFocusedEditableNodeIntoRect)
IPC_MESSAGE_HANDLER(InputMsg_SetEditCommandsForNextKeyEvent,
OnSetEditCommandsForNextKeyEvent)
- IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
- IPC_MESSAGE_HANDLER(ViewMsg_SaveImageAt, OnSaveImageAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetPageScale, OnSetPageScale)
IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
@@ -1310,7 +1307,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
IPC_MESSAGE_HANDLER(ViewMsg_EnumerateDirectoryResponse,
OnEnumerateDirectoryResponse)
- IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
@@ -1339,6 +1335,9 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(PageMsg_UpdateWindowScreenRect,
OnUpdateWindowScreenRect)
IPC_MESSAGE_HANDLER(PageMsg_SetZoomLevel, OnSetZoomLevel)
+ IPC_MESSAGE_HANDLER(PageMsg_WasHidden, OnPageWasHidden)
+ IPC_MESSAGE_HANDLER(PageMsg_WasShown, OnPageWasShown)
+
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateTopControlsState,
OnUpdateTopControlsState)
@@ -1367,14 +1366,6 @@ void RenderViewImpl::OnSelectWordAroundCaret() {
input_handler_->set_handling_input_event(false);
}
-void RenderViewImpl::OnCopyImageAt(int x, int y) {
- webview()->copyImageAt(WebPoint(x, y));
-}
-
-void RenderViewImpl::OnSaveImageAt(int x, int y) {
- webview()->saveImageAt(WebPoint(x, y));
-}
-
void RenderViewImpl::OnUpdateTargetURLAck() {
// Check if there is a targeturl waiting to be sent.
if (target_url_status_ == TARGET_PENDING)
@@ -1409,15 +1400,12 @@ void RenderViewImpl::OnScrollFocusedEditableNodeIntoRect(
return;
}
- blink::WebElement element = GetFocusedElement();
- bool will_animate = false;
- if (!element.isNull() && element.isEditable()) {
- rect_for_scrolled_focused_editable_node_ = rect;
- has_scrolled_focused_editable_node_into_rect_ = true;
- will_animate = webview()->scrollFocusedNodeIntoRect(rect);
- }
+ if (!webview()->scrollFocusedEditableElementIntoRect(rect))
+ return;
- if (!will_animate)
+ rect_for_scrolled_focused_editable_node_ = rect;
+ has_scrolled_focused_editable_node_into_rect_ = true;
+ if (!compositor()->hasPendingPageScaleAnimation())
GetWidget()->FocusChangeComplete();
}
@@ -1624,14 +1612,6 @@ void RenderViewImpl::printPage(WebLocalFrame* frame) {
PrintPage(frame, input_handler().handling_input_event()));
}
-void RenderViewImpl::saveImageFromDataURL(const blink::WebString& data_url) {
- // Note: We should basically send GURL but we use size-limited string instead
- // in order to send a larger data url to save a image for <canvas> or <img>.
- if (data_url.length() < kMaxLengthOfDataURLString)
- Send(new ViewHostMsg_SaveImageFromDataURL(
- GetRoutingID(), GetMainRenderFrame()->GetRoutingID(), data_url.utf8()));
-}
-
bool RenderViewImpl::enumerateChosenDirectory(
const WebString& path,
WebFileChooserCompletion* chooser_completion) {
@@ -1704,36 +1684,6 @@ bool RenderViewImpl::handleCurrentKeyboardEvent() {
return did_execute_command;
}
-bool RenderViewImpl::runFileChooser(
- const blink::WebFileChooserParams& params,
- WebFileChooserCompletion* chooser_completion) {
- // Do not open the file dialog in a hidden RenderView.
- if (is_hidden())
- return false;
- FileChooserParams ipc_params;
- if (params.directory)
- ipc_params.mode = FileChooserParams::UploadFolder;
- else if (params.multiSelect)
- ipc_params.mode = FileChooserParams::OpenMultiple;
- else if (params.saveAs)
- ipc_params.mode = FileChooserParams::Save;
- else
- ipc_params.mode = FileChooserParams::Open;
- ipc_params.title = params.title;
- ipc_params.default_file_name =
- blink::WebStringToFilePath(params.initialValue).BaseName();
- ipc_params.accept_types.reserve(params.acceptTypes.size());
- for (size_t i = 0; i < params.acceptTypes.size(); ++i)
- ipc_params.accept_types.push_back(params.acceptTypes[i]);
- ipc_params.need_local_path = params.needLocalPath;
-#if defined(OS_ANDROID)
- ipc_params.capture = params.useMediaCapture;
-#endif
- ipc_params.requestor = params.requestor;
-
- return ScheduleFileChooser(ipc_params, chooser_completion);
-}
-
void RenderViewImpl::SetValidationMessageDirection(
base::string16* wrapped_main_text,
blink::WebTextDirection main_text_hint,
@@ -1994,19 +1944,6 @@ void RenderViewImpl::show(WebNavigationPolicy policy) {
SetPendingWindowRect(initial_rect_);
}
-bool RenderViewImpl::requestPointerLock() {
- return mouse_lock_dispatcher_->LockMouse(webwidget_mouse_lock_target_.get());
-}
-
-void RenderViewImpl::requestPointerUnlock() {
- mouse_lock_dispatcher_->UnlockMouse(webwidget_mouse_lock_target_.get());
-}
-
-bool RenderViewImpl::isPointerLocked() {
- return mouse_lock_dispatcher_->IsMouseLockedTo(
- webwidget_mouse_lock_target_.get());
-}
-
void RenderViewImpl::onMouseDown(const WebNode& mouse_down_node) {
FOR_EACH_OBSERVER(
RenderViewObserver, observers_, OnMouseDown(mouse_down_node));
@@ -2062,8 +1999,7 @@ void RenderViewImpl::initializeLayerTreeView() {
if (input_handler_manager) {
input_handler_manager->AddInputHandler(
GetRoutingID(), rwc->GetInputHandler(), AsWeakPtr(),
- webkit_preferences_.enable_scroll_animator,
- UseGestureBasedWheelScrolling());
+ webkit_preferences_.enable_scroll_animator);
has_added_input_handler_ = true;
}
}
@@ -2320,10 +2256,6 @@ bool RenderViewImpl::GetContentStateImmediately() const {
return send_content_state_immediately_;
}
-blink::WebPageVisibilityState RenderViewImpl::GetVisibilityState() const {
- return visibilityState();
-}
-
void RenderViewImpl::DidStartLoading() {
main_render_frame_->didStartLoading(true);
}
@@ -2332,19 +2264,6 @@ void RenderViewImpl::DidStopLoading() {
main_render_frame_->didStopLoading();
}
-blink::WebElement RenderViewImpl::GetFocusedElement() const {
- if (!webview())
- return WebElement();
- WebFrame* focused_frame = webview()->focusedFrame();
- if (focused_frame) {
- WebDocument doc = focused_frame->document();
- if (!doc.isNull())
- return doc.focusedElement();
- }
-
- return WebElement();
-}
-
void RenderViewImpl::OnSetPageScale(float page_scale_factor) {
if (!webview())
return;
@@ -2444,17 +2363,15 @@ void RenderViewImpl::OnAllowBindings(int enabled_bindings_flags) {
main_render_frame_->MaybeEnableMojoBindings();
}
-void RenderViewImpl::OnDragTargetDragEnter(const DropData& drop_data,
- const gfx::Point& client_point,
- const gfx::Point& screen_point,
- WebDragOperationsMask ops,
- int key_modifiers) {
+void RenderViewImpl::OnDragTargetDragEnter(
+ const std::vector<DropData::Metadata>& drop_meta_data,
+ const gfx::Point& client_point,
+ const gfx::Point& screen_point,
+ WebDragOperationsMask ops,
+ int key_modifiers) {
WebDragOperation operation = webview()->dragTargetDragEnter(
- DropDataToWebDragData(drop_data),
- ConvertWindowPointToViewport(client_point),
- screen_point,
- ops,
- key_modifiers);
+ DropMetaDataToWebDragData(drop_meta_data), client_point, screen_point,
+ ops, key_modifiers);
Send(new DragHostMsg_UpdateDragCursor(GetRoutingID(), operation));
}
@@ -2476,11 +2393,12 @@ void RenderViewImpl::OnDragTargetDragLeave() {
webview()->dragTargetDragLeave();
}
-void RenderViewImpl::OnDragTargetDrop(const gfx::Point& client_point,
+void RenderViewImpl::OnDragTargetDrop(const DropData& drop_data,
+ const gfx::Point& client_point,
const gfx::Point& screen_point,
int key_modifiers) {
- webview()->dragTargetDrop(
- ConvertWindowPointToViewport(client_point), screen_point, key_modifiers);
+ webview()->dragTargetDrop(DropDataToWebDragData(drop_data), client_point,
+ screen_point, key_modifiers);
}
void RenderViewImpl::OnDragSourceEnded(const gfx::Point& client_point,
@@ -2513,42 +2431,6 @@ void RenderViewImpl::OnEnumerateDirectoryResponse(
enumeration_completions_.erase(id);
}
-void RenderViewImpl::OnFileChooserResponse(
- const std::vector<content::FileChooserFileInfo>& files) {
- // This could happen if we navigated to a different page before the user
- // closed the chooser.
- if (file_chooser_completions_.empty())
- return;
-
- // Convert Chrome's SelectedFileInfo list to WebKit's.
- WebVector<WebFileChooserCompletion::SelectedFileInfo> selected_files(
- files.size());
- for (size_t i = 0; i < files.size(); ++i) {
- WebFileChooserCompletion::SelectedFileInfo selected_file;
- selected_file.path = files[i].file_path.AsUTF16Unsafe();
- selected_file.displayName =
- base::FilePath(files[i].display_name).AsUTF16Unsafe();
- if (files[i].file_system_url.is_valid()) {
- selected_file.fileSystemURL = files[i].file_system_url;
- selected_file.length = files[i].length;
- selected_file.modificationTime = files[i].modification_time.ToDoubleT();
- selected_file.isDirectory = files[i].is_directory;
- }
- selected_files[i] = selected_file;
- }
-
- if (file_chooser_completions_.front()->completion)
- file_chooser_completions_.front()->completion->didChooseFile(
- selected_files);
- file_chooser_completions_.pop_front();
-
- // If there are more pending file chooser requests, schedule one now.
- if (!file_chooser_completions_.empty()) {
- Send(new ViewHostMsg_RunFileChooser(
- GetRoutingID(), file_chooser_completions_.front()->params));
- }
-}
-
void RenderViewImpl::OnEnableAutoResize(const gfx::Size& min_size,
const gfx::Size& max_size) {
DCHECK(disable_scrollbars_size_limit_.IsEmpty());
@@ -2698,7 +2580,8 @@ void RenderViewImpl::OnResize(const ResizeParams& params) {
TRACE_EVENT0("renderer", "RenderViewImpl::OnResize");
if (webview()) {
webview()->hidePopups();
- if (send_preferred_size_changes_) {
+ if (send_preferred_size_changes_ &&
+ webview()->mainFrame()->isWebLocalFrame()) {
webview()->mainFrame()->setCanHaveScrollbars(
ShouldDisplayScrollbars(params.new_size.width(),
params.new_size.height()));
@@ -2800,9 +2683,7 @@ void RenderViewImpl::Close() {
RenderThread::Get()->Send(new ViewHostMsg_Close_ACK(GetRoutingID()));
}
-void RenderViewImpl::OnWasHidden() {
- RenderWidget::OnWasHidden();
-
+void RenderViewImpl::OnPageWasHidden() {
#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
RenderThreadImpl::current()->video_capture_impl_manager()->
SuspendDevices(true);
@@ -2810,21 +2691,30 @@ void RenderViewImpl::OnWasHidden() {
speech_recognition_dispatcher_->AbortAllRecognitions();
#endif
- if (webview())
- webview()->setVisibilityState(visibilityState(), false);
+ if (webview()) {
+ // TODO(lfg): It's not correct to defer the page visibility to the main
+ // frame. Currently, this is done because the main frame may override the
+ // visibility of the page when prerendering. In order to fix this,
+ // prerendering must be made aware of OOPIFs. https://crbug.com/440544
+ blink::WebPageVisibilityState visibilityState =
+ GetMainRenderFrame() ? GetMainRenderFrame()->visibilityState()
+ : blink::WebPageVisibilityStateHidden;
+ webview()->setVisibilityState(visibilityState, false);
+ }
}
-void RenderViewImpl::OnWasShown(bool needs_repainting,
- const ui::LatencyInfo& latency_info) {
- RenderWidget::OnWasShown(needs_repainting, latency_info);
-
+void RenderViewImpl::OnPageWasShown() {
#if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
RenderThreadImpl::current()->video_capture_impl_manager()->
SuspendDevices(false);
#endif
- if (webview())
- webview()->setVisibilityState(visibilityState(), false);
+ if (webview()) {
+ blink::WebPageVisibilityState visibilityState =
+ GetMainRenderFrame() ? GetMainRenderFrame()->visibilityState()
+ : blink::WebPageVisibilityStateVisible;
+ webview()->setVisibilityState(visibilityState, false);
+ }
}
GURL RenderViewImpl::GetURLForGraphicsContext3D() {
@@ -3026,31 +2916,6 @@ void RenderViewImpl::SetScreenMetricsEmulationParameters(
}
}
-bool RenderViewImpl::ScheduleFileChooser(
- const FileChooserParams& params,
- WebFileChooserCompletion* completion) {
- static const size_t kMaximumPendingFileChooseRequests = 4;
- if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
- // This sanity check prevents too many file choose requests from getting
- // queued which could DoS the user. Getting these is most likely a
- // programming error (there are many ways to DoS the user so it's not
- // considered a "real" security check), either in JS requesting many file
- // choosers to pop up, or in a plugin.
- //
- // TODO(brettw) we might possibly want to require a user gesture to open
- // a file picker, which will address this issue in a better way.
- return false;
- }
-
- file_chooser_completions_.push_back(
- base::WrapUnique(new PendingFileChooser(params, completion)));
- if (file_chooser_completions_.size() == 1) {
- // Actually show the browse dialog when this is the first request.
- Send(new ViewHostMsg_RunFileChooser(GetRoutingID(), params));
- }
- return true;
-}
-
blink::WebSpeechRecognizer* RenderViewImpl::speechRecognizer() {
if (!speech_recognition_dispatcher_)
speech_recognition_dispatcher_ = new SpeechRecognitionDispatcher(this);
@@ -3100,19 +2965,6 @@ double RenderViewImpl::zoomFactorToZoomLevel(double factor) const {
return ZoomFactorToZoomLevel(factor);
}
-blink::WebPageVisibilityState RenderViewImpl::visibilityState() const {
- blink::WebPageVisibilityState current_state = is_hidden() ?
- blink::WebPageVisibilityStateHidden :
- blink::WebPageVisibilityStateVisible;
- blink::WebPageVisibilityState override_state = current_state;
- // TODO(jam): move this method to WebFrameClient.
- if (GetContentClient()->renderer()->
- ShouldOverridePageVisibilityState(main_render_frame_,
- &override_state))
- return override_state;
- return current_state;
-}
-
void RenderViewImpl::draggableRegionsChanged() {
FOR_EACH_OBSERVER(
RenderViewObserver,
@@ -3153,7 +3005,7 @@ WebContentDetectionResult RenderViewImpl::detectContentAround(
void RenderViewImpl::scheduleContentIntent(const WebURL& intent,
bool is_main_frame) {
// Introduce a short delay so that the user can notice the content.
- base::MessageLoop::current()->PostDelayedTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&RenderViewImpl::LaunchAndroidContentIntent, AsWeakPtr(),
intent, expected_content_intent_id_, is_main_frame),
diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h
index 8d292c2c9d1..1ebdb174b2e 100644
--- a/chromium/content/renderer/render_view_impl.h
+++ b/chromium/content/renderer/render_view_impl.h
@@ -33,19 +33,18 @@
#include "content/common/navigation_gesture.h"
#include "content/common/page_message_enums.h"
#include "content/common/view_message_enums.h"
+#include "content/public/common/drop_data.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/referrer.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/top_controls_state.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_view.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
#include "content/renderer/render_widget_owner_delegate.h"
#include "content/renderer/stats_collection_observer.h"
#include "ipc/ipc_platform_file.h"
-#include "third_party/WebKit/public/platform/WebPageVisibilityState.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebAXObject.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
@@ -121,7 +120,6 @@ namespace content {
class HistoryController;
class HistoryEntry;
-class MouseLockDispatcher;
class PageState;
class RenderViewImplTest;
class RenderViewObserver;
@@ -130,7 +128,6 @@ class RendererDateTimePicker;
class RendererWebColorChooserImpl;
class SpeechRecognitionDispatcher;
class WebPluginDelegateProxy;
-struct DropData;
struct FaviconURL;
struct FileChooserParams;
struct FileChooserFileInfo;
@@ -194,10 +191,6 @@ class CONTENT_EXPORT RenderViewImpl
send_content_state_immediately_ = value;
}
- MouseLockDispatcher* mouse_lock_dispatcher() {
- return mouse_lock_dispatcher_;
- }
-
HistoryController* history_controller() {
return history_controller_.get();
}
@@ -293,9 +286,6 @@ class CONTENT_EXPORT RenderViewImpl
// Most methods are handled by RenderWidget.
void didFocus() override;
void show(blink::WebNavigationPolicy policy) override;
- bool requestPointerLock() override;
- void requestPointerUnlock() override;
- bool isPointerLocked() override;
void didHandleGestureEvent(const blink::WebGestureEvent& event,
bool event_cancelled) override;
void onMouseDown(const blink::WebNode& mouse_down_node) override;
@@ -347,12 +337,8 @@ class CONTENT_EXPORT RenderViewImpl
bool enumerateChosenDirectory(
const blink::WebString& path,
blink::WebFileChooserCompletion* chooser_completion) override;
- void saveImageFromDataURL(const blink::WebString& data_url) override;
void didCancelCompositionOnSelectionChange() override;
bool handleCurrentKeyboardEvent() override;
- bool runFileChooser(
- const blink::WebFileChooserParams& params,
- blink::WebFileChooserCompletion* chooser_completion) override;
void SetValidationMessageDirection(base::string16* main_text,
blink::WebTextDirection main_text_hint,
base::string16* sub_text,
@@ -395,7 +381,6 @@ class CONTENT_EXPORT RenderViewImpl
void pageScaleFactorChanged() override;
virtual double zoomLevelToZoomFactor(double zoom_level) const;
virtual double zoomFactorToZoomLevel(double factor) const;
- blink::WebPageVisibilityState visibilityState() const override;
void draggableRegionsChanged() override;
void pageImportanceSignalsChanged() override;
@@ -428,7 +413,6 @@ class CONTENT_EXPORT RenderViewImpl
bool ShouldDisplayScrollbars(int width, int height) const override;
int GetEnabledBindings() const override;
bool GetContentStateImmediately() const override;
- blink::WebPageVisibilityState GetVisibilityState() const override;
void DidStartLoading() override;
void DidStopLoading() override;
void Repaint(const gfx::Size& size) override;
@@ -461,9 +445,6 @@ class CONTENT_EXPORT RenderViewImpl
void Close() override;
void OnResize(const ResizeParams& params) override;
void OnSetFocus(bool enable) override;
- void OnWasHidden() override;
- void OnWasShown(bool needs_repainting,
- const ui::LatencyInfo& latency_info) override;
GURL GetURLForGraphicsContext3D() override;
void OnImeSetComposition(
const base::string16& text,
@@ -620,8 +601,6 @@ class CONTENT_EXPORT RenderViewImpl
void OnShowContextMenu(ui::MenuSourceType source_type,
const gfx::Point& location);
- void OnCopyImageAt(int x, int y);
- void OnSaveImageAt(int x, int y);
void OnDeterminePageLanguage();
void OnDisableScrollbarsForSmallWindows(
const gfx::Size& disable_scrollbars_size_limit);
@@ -629,14 +608,17 @@ class CONTENT_EXPORT RenderViewImpl
const gfx::Point& screen_point,
blink::WebDragOperation drag_operation);
void OnDragSourceSystemDragEnded();
- void OnDragTargetDrop(const gfx::Point& client_pt,
+ void OnDragTargetDrop(const DropData& drop_data,
+ const gfx::Point& client_pt,
const gfx::Point& screen_pt,
int key_modifiers);
- void OnDragTargetDragEnter(const DropData& drop_data,
- const gfx::Point& client_pt,
- const gfx::Point& screen_pt,
- blink::WebDragOperationsMask operations_allowed,
- int key_modifiers);
+ // Real data that is dragged is not included at DragEnter time.
+ void OnDragTargetDragEnter(
+ const std::vector<DropData::Metadata>& drop_meta_data,
+ const gfx::Point& client_pt,
+ const gfx::Point& screen_pt,
+ blink::WebDragOperationsMask operations_allowed,
+ int key_modifiers);
void OnDragTargetDragLeave();
void OnDragTargetDragOver(const gfx::Point& client_pt,
const gfx::Point& screen_pt,
@@ -647,8 +629,6 @@ class CONTENT_EXPORT RenderViewImpl
void OnDisableAutoResize(const gfx::Size& new_size);
void OnEnumerateDirectoryResponse(int id,
const std::vector<base::FilePath>& paths);
- void OnFileChooserResponse(
- const std::vector<content::FileChooserFileInfo>& files);
void OnMediaPlayerActionAt(const gfx::Point& location,
const blink::WebMediaPlayerAction& action);
void OnPluginActionAt(const gfx::Point& location,
@@ -686,6 +666,8 @@ class CONTENT_EXPORT RenderViewImpl
// Page message handlers -----------------------------------------------------
void OnUpdateWindowScreenRect(gfx::Rect window_screen_rect);
void OnSetZoomLevel(PageMsg_SetZoomLevel_Command command, double zoom_level);
+ void OnPageWasHidden();
+ void OnPageWasShown();
// Adding a new message handler? Please add it in alphabetical order above
// and put it in the same position in the .cc file.
@@ -694,9 +676,6 @@ class CONTENT_EXPORT RenderViewImpl
// Check whether the preferred size has changed.
void CheckPreferredSize();
- // Gets the currently focused element, if any.
- blink::WebElement GetFocusedElement() const;
-
#if defined(OS_ANDROID)
// Launch an Android content intent with the given URL.
void LaunchAndroidContentIntent(const GURL& intent_url,
@@ -904,9 +883,6 @@ class CONTENT_EXPORT RenderViewImpl
// initialized.
SpeechRecognitionDispatcher* speech_recognition_dispatcher_;
- // Mouse Lock dispatcher attached to this view.
- MouseLockDispatcher* mouse_lock_dispatcher_;
-
std::unique_ptr<HistoryController> history_controller_;
#if defined(OS_ANDROID)
@@ -926,13 +902,6 @@ class CONTENT_EXPORT RenderViewImpl
// Misc ----------------------------------------------------------------------
- // The current and pending file chooser completion objects. If the queue is
- // nonempty, the first item represents the currently running file chooser
- // callback, and the remaining elements are the other file chooser completion
- // still waiting to be run (in order).
- struct PendingFileChooser;
- std::deque<std::unique_ptr<PendingFileChooser>> file_chooser_completions_;
-
// The current directory enumeration callback
std::map<int, blink::WebFileChooserCompletion*> enumeration_completions_;
int enumeration_completion_id_;
@@ -950,9 +919,6 @@ class CONTENT_EXPORT RenderViewImpl
// is fine.
base::ObserverList<RenderViewObserver> observers_;
- // Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface.
- std::unique_ptr<MouseLockDispatcher::LockTarget> webwidget_mouse_lock_target_;
-
// This field stores drag/drop related info for the event that is currently
// being handled. If the current event results in starting a drag/drop
// session, this info is sent to the browser along with other drag/drop info.
diff --git a/chromium/content/renderer/render_view_mouse_lock_dispatcher.h b/chromium/content/renderer/render_view_mouse_lock_dispatcher.h
deleted file mode 100644
index 984a40e0984..00000000000
--- a/chromium/content/renderer/render_view_mouse_lock_dispatcher.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_RENDER_VIEW_MOUSE_LOCK_DISPATCHER_H_
-#define CONTENT_RENDERER_RENDER_VIEW_MOUSE_LOCK_DISPATCHER_H_
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "content/public/renderer/render_view_observer.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
-
-namespace content {
-class RenderViewImpl;
-
-// RenderViewMouseLockDispatcher is owned by RenderViewImpl.
-class RenderViewMouseLockDispatcher : public MouseLockDispatcher,
- public RenderViewObserver {
- public:
- explicit RenderViewMouseLockDispatcher(RenderViewImpl* render_view_impl);
- ~RenderViewMouseLockDispatcher() override;
-
- private:
- // MouseLockDispatcher implementation.
- void SendLockMouseRequest(bool unlocked_by_target) override;
- void SendUnlockMouseRequest() override;
-
- // RenderView::Observer implementation.
- bool OnMessageReceived(const IPC::Message& message) override;
-
- void OnLockMouseACK(bool succeeded);
-
- RenderViewImpl* render_view_impl_;
-
- DISALLOW_COPY_AND_ASSIGN(RenderViewMouseLockDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_RENDER_VIEW_MOUSE_LOCK_DISPATCHER_H_
diff --git a/chromium/content/renderer/render_widget.cc b/chromium/content/renderer/render_widget.cc
index 66a8ecc0355..129ed07f6eb 100644
--- a/chromium/content/renderer/render_widget.cc
+++ b/chromium/content/renderer/render_widget.cc
@@ -23,17 +23,11 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_synthetic_delay.h"
#include "build/build_config.h"
-#include "cc/base/switches.h"
-#include "cc/debug/benchmark_instrumentation.h"
#include "cc/output/output_surface.h"
-#include "cc/output/vulkan_in_process_context_provider.h"
#include "cc/scheduler/begin_frame_source.h"
-#include "cc/trees/layer_tree_host.h"
#include "components/scheduler/renderer/render_widget_scheduling_state.h"
#include "components/scheduler/renderer/renderer_scheduler.h"
#include "content/common/content_switches_internal.h"
-#include "content/common/gpu/client/context_provider_command_buffer.h"
-#include "content/common/gpu_process_launch_causes.h"
#include "content/common/input/synthetic_gesture_packet.h"
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
@@ -46,10 +40,7 @@
#include "content/renderer/cursor_utils.h"
#include "content/renderer/devtools/render_widget_screen_metrics_emulator.h"
#include "content/renderer/external_popup_menu.h"
-#include "content/renderer/gpu/compositor_output_surface.h"
-#include "content/renderer/gpu/delegated_compositor_output_surface.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
-#include "content/renderer/gpu/mailbox_output_surface.h"
#include "content/renderer/gpu/queue_message_swap_promise.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/ime_event_guard.h"
@@ -63,7 +54,6 @@
#include "content/renderer/render_widget_owner_delegate.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "content/renderer/resizing_mode_selector.h"
-#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "ipc/ipc_sync_message.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebCursorInfo.h"
@@ -93,8 +83,6 @@
#if defined(OS_ANDROID)
#include <android/keycodes.h>
-#include "content/renderer/android/synchronous_compositor_filter.h"
-#include "content/renderer/android/synchronous_compositor_output_surface.h"
#endif
#if defined(OS_POSIX)
@@ -140,6 +128,29 @@ namespace {
typedef std::map<std::string, ui::TextInputMode> TextInputModeMap;
+class WebWidgetLockTarget : public content::MouseLockDispatcher::LockTarget {
+ public:
+ explicit WebWidgetLockTarget(blink::WebWidget* webwidget)
+ : webwidget_(webwidget) {}
+
+ void OnLockMouseACK(bool succeeded) override {
+ if (succeeded)
+ webwidget_->didAcquirePointerLock();
+ else
+ webwidget_->didNotAcquirePointerLock();
+ }
+
+ void OnMouseLockLost() override { webwidget_->didLosePointerLock(); }
+
+ bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
+ // The WebWidget handles mouse lock in Blink's handleInputEvent().
+ return false;
+ }
+
+ private:
+ blink::WebWidget* webwidget_;
+};
+
class TextInputModeMapSingleton {
public:
static TextInputModeMapSingleton* GetInstance() {
@@ -189,7 +200,7 @@ content::RenderWidgetInputHandlerDelegate* GetRenderWidgetInputHandlerDelegate(
content::RenderWidget* widget) {
#if defined(MOJO_SHELL_CLIENT)
const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
- if (content::MojoShellConnection::Get() &&
+ if (content::MojoShellConnection::GetForProcess() &&
cmdline.HasSwitch(switches::kUseMusInRenderer)) {
return content::RenderWidgetMusConnection::GetOrCreate(
widget->routing_id());
@@ -239,7 +250,6 @@ RenderWidget::RenderWidget(CompositorDependencies* compositor_deps,
pending_window_rect_count_(0),
screen_info_(screen_info),
device_scale_factor_(screen_info_.deviceScaleFactor),
- next_output_surface_id_(0),
#if defined(OS_ANDROID)
text_field_is_dirty_(false),
#endif
@@ -374,6 +384,8 @@ bool RenderWidget::DoInit(int32_t opener_id,
opener_id_ = opener_id;
webwidget_ = web_widget;
+ webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_));
+ mouse_lock_dispatcher_.reset(new RenderWidgetMouseLockDispatcher(this));
bool result = true;
if (create_widget_message)
@@ -435,7 +447,7 @@ gfx::Rect RenderWidget::AdjustValidationMessageAnchor(const gfx::Rect& anchor) {
return anchor;
}
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(USE_EXTERNAL_POPUP_MENU)
void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
ExternalPopupMenu* popup,
RenderWidgetScreenMetricsEmulator* emulator) {
@@ -450,6 +462,10 @@ void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
}
bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
+ if (mouse_lock_dispatcher_ &&
+ mouse_lock_dispatcher_->OnMessageReceived(message))
+ return true;
+
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
IPC_MESSAGE_HANDLER(InputMsg_HandleInputEvent, OnHandleInputEvent)
@@ -467,7 +483,6 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
OnEnableDeviceEmulation)
IPC_MESSAGE_HANDLER(ViewMsg_DisableDeviceEmulation,
OnDisableDeviceEmulation)
- IPC_MESSAGE_HANDLER(ViewMsg_ColorProfile, OnColorProfile)
IPC_MESSAGE_HANDLER(ViewMsg_ChangeResizeRect, OnChangeResizeRect)
IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
IPC_MESSAGE_HANDLER(ViewMsg_WasShown, OnWasShown)
@@ -596,10 +611,6 @@ void RenderWidget::OnDisableDeviceEmulation() {
screen_metrics_emulator_.reset();
}
-void RenderWidget::OnColorProfile(const std::vector<char>& color_profile) {
- SetDeviceColorProfile(color_profile);
-}
-
void RenderWidget::OnChangeResizeRect(const gfx::Rect& resizer_rect) {
if (resizer_rect_ == resizer_rect)
return;
@@ -704,119 +715,9 @@ std::unique_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(
// For widgets that are never visible, we don't start the compositor, so we
// never get a request for a cc::OutputSurface.
DCHECK(!compositor_never_visible_);
-
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- bool use_software = fallback;
- if (command_line.HasSwitch(switches::kDisableGpuCompositing))
- use_software = true;
-
-#if defined(MOJO_SHELL_CLIENT)
- if (MojoShellConnection::Get() && !use_software &&
- command_line.HasSwitch(switches::kUseMusInRenderer)) {
- RenderWidgetMusConnection* connection =
- RenderWidgetMusConnection::GetOrCreate(routing_id());
- return connection->CreateOutputSurface();
- }
-#endif
-
- uint32_t output_surface_id = next_output_surface_id_++;
-
- if (command_line.HasSwitch(switches::kEnableVulkan)) {
- scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider =
- cc::VulkanInProcessContextProvider::Create();
- if (vulkan_context_provider) {
- return base::WrapUnique(new DelegatedCompositorOutputSurface(
- routing_id(), output_surface_id, nullptr, nullptr,
- vulkan_context_provider, frame_swap_message_queue_));
- }
- }
-
- // Create a gpu process channel and verify we want to use GPU compositing
- // before creating any context providers.
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host;
- if (!use_software) {
- gpu_channel_host = RenderThreadImpl::current()->EstablishGpuChannelSync(
- CAUSE_FOR_GPU_LAUNCH_RENDERER_VERIFY_GPU_COMPOSITING);
- if (!gpu_channel_host) {
- // Cause the compositor to wait and try again.
- return nullptr;
- }
- // We may get a valid channel, but with a software renderer. In that case,
- // disable GPU compositing.
- if (gpu_channel_host->gpu_info().software_rendering)
- use_software = true;
- }
-
- if (use_software) {
- return base::WrapUnique(new DelegatedCompositorOutputSurface(
- routing_id(), output_surface_id, nullptr, nullptr, nullptr,
- frame_swap_message_queue_));
- }
-
- scoped_refptr<ContextProviderCommandBuffer> worker_context_provider =
- RenderThreadImpl::current()->SharedCompositorWorkerContextProvider();
- if (!worker_context_provider) {
- // Cause the compositor to wait and try again.
- return nullptr;
- }
-
- // The renderer compositor context doesn't do a lot of stuff, so we don't
- // expect it to need a lot of space for commands or transfer. Raster and
- // uploads happen on the worker context instead.
- gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
-
- // This is for an offscreen context for the compositor. So the default
- // framebuffer doesn't need alpha, depth, stencil, antialiasing.
- gpu::gles2::ContextCreationAttribHelper attributes;
- attributes.alpha_size = -1;
- attributes.depth_size = 0;
- attributes.stencil_size = 0;
- attributes.samples = 0;
- attributes.sample_buffers = 0;
- attributes.bind_generates_resource = false;
- attributes.lose_context_when_out_of_memory = true;
-
- constexpr bool automatic_flushes = false;
- constexpr bool support_locking = false;
-
- // The compositor context shares resources with the worker context unless
- // the worker is async.
- ContextProviderCommandBuffer* share_context = worker_context_provider.get();
- if (compositor_deps_->IsAsyncWorkerContextEnabled())
- share_context = nullptr;
-
- scoped_refptr<ContextProviderCommandBuffer> context_provider(
- new ContextProviderCommandBuffer(
- std::move(gpu_channel_host), gpu::GPU_STREAM_DEFAULT,
- gpu::GpuStreamPriority::NORMAL, gpu::kNullSurfaceHandle,
- GetURLForGraphicsContext3D(), gfx::PreferIntegratedGpu,
- automatic_flushes, support_locking, limits, attributes, share_context,
- command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT));
-
-#if defined(OS_ANDROID)
- if (RenderThreadImpl::current()->sync_compositor_message_filter()) {
- return base::WrapUnique(new SynchronousCompositorOutputSurface(
- context_provider, worker_context_provider, routing_id(),
- output_surface_id,
- RenderThreadImpl::current()->sync_compositor_message_filter(),
- frame_swap_message_queue_));
- }
-#endif
-
- // Composite-to-mailbox is currently used for layout tests in order to cause
- // them to draw inside in the renderer to do the readback there. This should
- // no longer be the case when crbug.com/311404 is fixed.
- if (RenderThreadImpl::current()->layout_test_mode()) {
- return base::WrapUnique(new MailboxOutputSurface(
- routing_id(), output_surface_id, std::move(context_provider),
- std::move(worker_context_provider), frame_swap_message_queue_,
- cc::RGBA_8888));
- }
-
- return base::WrapUnique(new DelegatedCompositorOutputSurface(
- routing_id(), output_surface_id, std::move(context_provider),
- std::move(worker_context_provider), nullptr, frame_swap_message_queue_));
+ return RenderThreadImpl::current()->CreateCompositorOutputSurface(
+ fallback, routing_id_, frame_swap_message_queue_,
+ GetURLForGraphicsContext3D());
}
std::unique_ptr<cc::BeginFrameSource>
@@ -915,13 +816,6 @@ void RenderWidget::WillBeginCompositorFrame() {
WillBeginCompositorFrame());
}
-void RenderWidget::ReportFixedRasterScaleUseCounters(
- bool has_blurry_content,
- bool has_potential_performance_regression) {
- webwidget_->reportFixedRasterScaleUseCounters(
- has_blurry_content, has_potential_performance_regression);
-}
-
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetInputHandlerDelegate
@@ -937,27 +831,6 @@ bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const {
return true;
}
-void RenderWidget::ObserveWheelEventAndResult(
- const blink::WebMouseWheelEvent& wheel_event,
- const gfx::Vector2dF& wheel_unused_delta,
- bool event_processed) {
- if (!compositor_deps_->IsElasticOverscrollEnabled())
- return;
-
- cc::InputHandlerScrollResult scroll_result;
- scroll_result.did_scroll = event_processed;
- scroll_result.did_overscroll_root = !wheel_unused_delta.IsZero();
- scroll_result.unused_scroll_delta = wheel_unused_delta;
-
- RenderThreadImpl* render_thread = RenderThreadImpl::current();
- InputHandlerManager* input_handler_manager =
- render_thread ? render_thread->input_handler_manager() : NULL;
- if (input_handler_manager) {
- input_handler_manager->ObserveWheelEventAndResultOnMainThread(
- routing_id_, wheel_event, scroll_result);
- }
-}
-
void RenderWidget::ObserveGestureEventAndResult(
const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& unused_delta,
@@ -2099,4 +1972,17 @@ float RenderWidget::GetOriginalDeviceScaleFactor() const {
device_scale_factor_;
}
+bool RenderWidget::requestPointerLock() {
+ return mouse_lock_dispatcher_->LockMouse(webwidget_mouse_lock_target_.get());
+}
+
+void RenderWidget::requestPointerUnlock() {
+ mouse_lock_dispatcher_->UnlockMouse(webwidget_mouse_lock_target_.get());
+}
+
+bool RenderWidget::isPointerLocked() {
+ return mouse_lock_dispatcher_->IsMouseLockedTo(
+ webwidget_mouse_lock_target_.get());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/render_widget.h b/chromium/content/renderer/render_widget.h
index 181222d7c44..8cb0010653d 100644
--- a/chromium/content/renderer/render_widget.h
+++ b/chromium/content/renderer/render_widget.h
@@ -27,6 +27,8 @@
#include "content/renderer/input/render_widget_input_handler.h"
#include "content/renderer/input/render_widget_input_handler_delegate.h"
#include "content/renderer/message_delivery_policy.h"
+#include "content/renderer/mouse_lock_dispatcher.h"
+#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/public/platform/WebDisplayMode.h"
@@ -39,7 +41,6 @@
#include "third_party/WebKit/public/web/WebTouchAction.h"
#include "third_party/WebKit/public/web/WebWidget.h"
#include "third_party/WebKit/public/web/WebWidgetClient.h"
-#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ime/text_input_mode.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/base/ui_base_types.h"
@@ -202,16 +203,10 @@ class CONTENT_EXPORT RenderWidget
void RequestScheduleAnimation() override;
void UpdateVisualState() override;
void WillBeginCompositorFrame() override;
- void ReportFixedRasterScaleUseCounters(
- bool has_blurry_content,
- bool has_potential_performance_regression) override;
// RenderWidgetInputHandlerDelegate
void FocusChangeComplete() override;
bool HasTouchEventHandlersAt(const gfx::Point& point) const override;
- void ObserveWheelEventAndResult(const blink::WebMouseWheelEvent& wheel_event,
- const gfx::Vector2dF& wheel_unused_delta,
- bool event_processed) override;
void ObserveGestureEventAndResult(const blink::WebGestureEvent& gesture_event,
const gfx::Vector2dF& unused_delta,
bool event_processed) override;
@@ -262,6 +257,9 @@ class CONTENT_EXPORT RenderWidget
void showImeIfNeeded() override;
void convertViewportToWindow(blink::WebRect* rect) override;
void convertWindowToViewport(blink::WebFloatRect* rect) override;
+ bool requestPointerLock() override;
+ void requestPointerUnlock() override;
+ bool isPointerLocked() override;
// Override point to obtain that the current input method state and caret
// position.
@@ -346,9 +344,6 @@ class CONTENT_EXPORT RenderWidget
// the new value will be sent to the browser process.
void UpdateSelectionBounds();
- // Called by the compositor to forward a proto that represents serialized
- // compositor state.
-
virtual void GetSelectionBounds(gfx::Rect* start, gfx::Rect* end);
void OnShowHostContextMenu(ContextMenuParams* params);
@@ -366,6 +361,10 @@ class CONTENT_EXPORT RenderWidget
// Indicates whether this widget has focus.
bool has_focus() const { return has_focus_; }
+ MouseLockDispatcher* mouse_lock_dispatcher() {
+ return mouse_lock_dispatcher_.get();
+ }
+
protected:
// Friend RefCounted so that the dtor can be non-public. Using this class
// without ref-counting is an error.
@@ -424,7 +423,7 @@ class CONTENT_EXPORT RenderWidget
// Used to force the size of a window when running layout tests.
void SetWindowRectSynchronously(const gfx::Rect& new_window_rect);
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(USE_EXTERNAL_POPUP_MENU)
void SetExternalPopupOriginAdjustmentsForEmulation(
ExternalPopupMenu* popup,
RenderWidgetScreenMetricsEmulator* emulator);
@@ -442,7 +441,6 @@ class CONTENT_EXPORT RenderWidget
virtual void OnResize(const ResizeParams& params);
void OnEnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
void OnDisableDeviceEmulation();
- void OnColorProfile(const std::vector<char>& color_profile);
void OnChangeResizeRect(const gfx::Rect& resizer_rect);
virtual void OnWasHidden();
virtual void OnWasShown(bool needs_repainting,
@@ -717,8 +715,6 @@ class CONTENT_EXPORT RenderWidget
std::queue<SyntheticGestureCompletionCallback>
pending_synthetic_gesture_callbacks_;
- uint32_t next_output_surface_id_;
-
#if defined(OS_ANDROID)
// Indicates value in the focused text field is in dirty state, i.e. modified
// by script etc., not by user input.
@@ -760,6 +756,12 @@ class CONTENT_EXPORT RenderWidget
std::unique_ptr<scheduler::RenderWidgetSchedulingState>
render_widget_scheduling_state_;
+ // Mouse Lock dispatcher attached to this view.
+ std::unique_ptr<RenderWidgetMouseLockDispatcher> mouse_lock_dispatcher_;
+
+ // Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface.
+ std::unique_ptr<MouseLockDispatcher::LockTarget> webwidget_mouse_lock_target_;
+
private:
// When emulated, this returns original device scale factor.
float GetOriginalDeviceScaleFactor() const;
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.cc b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
index 30a6372c082..10df6034b8f 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
@@ -145,8 +145,7 @@ class PepperWidget : public WebWidget {
size_ = size;
WebRect plugin_rect(0, 0, size_.width, size_.height);
- widget_->plugin()->ViewChanged(plugin_rect, plugin_rect, plugin_rect,
- std::vector<gfx::Rect>());
+ widget_->plugin()->ViewChanged(plugin_rect, plugin_rect, plugin_rect);
widget_->Invalidate();
}
diff --git a/chromium/content/renderer/render_view_mouse_lock_dispatcher.cc b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
index bdd747b044e..970bef08fd6 100644
--- a/chromium/content/renderer/render_view_mouse_lock_dispatcher.cc
+++ b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/render_view_mouse_lock_dispatcher.h"
+#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_view_impl.h"
+#include "ipc/ipc_message.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h"
@@ -15,31 +16,29 @@ using blink::WebUserGestureIndicator;
namespace content {
-RenderViewMouseLockDispatcher::RenderViewMouseLockDispatcher(
- RenderViewImpl* render_view_impl)
- : RenderViewObserver(render_view_impl),
- render_view_impl_(render_view_impl) {
-}
+RenderWidgetMouseLockDispatcher::RenderWidgetMouseLockDispatcher(
+ RenderWidget* render_widget)
+ : render_widget_(render_widget) {}
-RenderViewMouseLockDispatcher::~RenderViewMouseLockDispatcher() {
-}
+RenderWidgetMouseLockDispatcher::~RenderWidgetMouseLockDispatcher() {}
-void RenderViewMouseLockDispatcher::SendLockMouseRequest(
+void RenderWidgetMouseLockDispatcher::SendLockMouseRequest(
bool unlocked_by_target) {
bool user_gesture = WebUserGestureIndicator::isProcessingUserGesture();
- Send(new ViewHostMsg_LockMouse(routing_id(), user_gesture, unlocked_by_target,
- false));
+ render_widget_->Send(new ViewHostMsg_LockMouse(
+ render_widget_->routing_id(), user_gesture, unlocked_by_target, false));
}
-void RenderViewMouseLockDispatcher::SendUnlockMouseRequest() {
- Send(new ViewHostMsg_UnlockMouse(routing_id()));
+void RenderWidgetMouseLockDispatcher::SendUnlockMouseRequest() {
+ render_widget_->Send(
+ new ViewHostMsg_UnlockMouse(render_widget_->routing_id()));
}
-bool RenderViewMouseLockDispatcher::OnMessageReceived(
+bool RenderWidgetMouseLockDispatcher::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RenderViewMouseLockDispatcher, message)
+ IPC_BEGIN_MESSAGE_MAP(RenderWidgetMouseLockDispatcher, message)
IPC_MESSAGE_HANDLER(ViewMsg_LockMouse_ACK, OnLockMouseACK)
IPC_MESSAGE_FORWARD(ViewMsg_MouseLockLost,
static_cast<MouseLockDispatcher*>(this),
@@ -49,7 +48,7 @@ bool RenderViewMouseLockDispatcher::OnMessageReceived(
return handled;
}
-void RenderViewMouseLockDispatcher::OnLockMouseACK(bool succeeded) {
+void RenderWidgetMouseLockDispatcher::OnLockMouseACK(bool succeeded) {
// Notify the base class.
MouseLockDispatcher::OnLockMouseACK(succeeded);
@@ -59,8 +58,8 @@ void RenderViewMouseLockDispatcher::OnLockMouseACK(bool succeeded) {
// Mouse Capture is implicitly given for the duration of a drag event, and
// sends all mouse events to the initial target of the drag.
// If Lock is entered it supercedes any in progress Capture.
- if (succeeded && render_view_impl_->GetWidget()->webwidget())
- render_view_impl_->GetWidget()->webwidget()->mouseCaptureLost();
+ if (succeeded && render_widget_->webwidget())
+ render_widget_->webwidget()->mouseCaptureLost();
}
} // namespace content
diff --git a/chromium/content/renderer/render_widget_mouse_lock_dispatcher.h b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.h
new file mode 100644
index 00000000000..ed5ecee0259
--- /dev/null
+++ b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
+#define CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "content/renderer/mouse_lock_dispatcher.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class RenderWidget;
+
+// RenderWidgetMouseLockDispatcher is owned by RenderWidget.
+class RenderWidgetMouseLockDispatcher : public MouseLockDispatcher {
+ public:
+ explicit RenderWidgetMouseLockDispatcher(RenderWidget* render_widget);
+ ~RenderWidgetMouseLockDispatcher() override;
+
+ bool OnMessageReceived(const IPC::Message& message);
+
+ private:
+ // MouseLockDispatcher implementation.
+ void SendLockMouseRequest(bool unlocked_by_target) override;
+ void SendUnlockMouseRequest() override;
+
+ void OnLockMouseACK(bool succeeded);
+
+ RenderWidget* render_widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetMouseLockDispatcher);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
diff --git a/chromium/content/renderer/render_widget_unittest.cc b/chromium/content/renderer/render_widget_unittest.cc
index 91b687f20d9..9b7ac2ea586 100644
--- a/chromium/content/renderer/render_widget_unittest.cc
+++ b/chromium/content/renderer/render_widget_unittest.cc
@@ -4,6 +4,7 @@
#include "content/renderer/render_widget.h"
+#include <tuple>
#include <vector>
#include "base/macros.h"
@@ -167,7 +168,7 @@ TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
InputHostMsg_HandleInputEvent_ACK::Param params;
InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- InputEventAckState ack_state = base::get<0>(params).state;
+ InputEventAckState ack_state = std::get<0>(params).state;
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
widget()->sink()->ClearMessages();
@@ -185,7 +186,7 @@ TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
message = widget()->sink()->GetMessageAt(0);
EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- ack_state = base::get<0>(params).state;
+ ack_state = std::get<0>(params).state;
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
widget()->sink()->ClearMessages();
}
@@ -212,7 +213,7 @@ TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
InputHostMsg_HandleInputEvent_ACK::Param params;
InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- InputEventAckState ack_state = base::get<0>(params).state;
+ InputEventAckState ack_state = std::get<0>(params).state;
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
widget()->sink()->ClearMessages();
@@ -223,7 +224,7 @@ TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
message = widget()->sink()->GetMessageAt(0);
EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- ack_state = base::get<0>(params).state;
+ ack_state = std::get<0>(params).state;
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
widget()->sink()->ClearMessages();
}
@@ -248,7 +249,7 @@ TEST_F(RenderWidgetUnittest, EventOverscroll) {
ASSERT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
InputHostMsg_HandleInputEvent_ACK::Param params;
InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
- const InputEventAck& ack = base::get<0>(params);
+ const InputEventAck& ack = std::get<0>(params);
ASSERT_EQ(ack.type, scroll.type);
ASSERT_TRUE(ack.overscroll);
EXPECT_EQ(gfx::Vector2dF(0, 10), ack.overscroll->accumulated_overscroll);
@@ -269,7 +270,7 @@ TEST_F(RenderWidgetUnittest, FlingOverscroll) {
ASSERT_EQ(InputHostMsg_DidOverscroll::ID, message->type());
InputHostMsg_DidOverscroll::Param params;
InputHostMsg_DidOverscroll::Read(message, &params);
- const DidOverscrollParams& overscroll = base::get<0>(params);
+ const DidOverscrollParams& overscroll = std::get<0>(params);
EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.latest_overscroll_delta);
EXPECT_EQ(gfx::Vector2dF(5, 5), overscroll.accumulated_overscroll);
EXPECT_EQ(gfx::PointF(1, 1), overscroll.causal_event_viewport_point);
diff --git a/chromium/content/renderer/renderer.sb b/chromium/content/renderer/renderer.sb
index 8c0f569abcc..7afdf86b297 100644
--- a/chromium/content/renderer/renderer.sb
+++ b/chromium/content/renderer/renderer.sb
@@ -34,18 +34,6 @@
(allow file-read-metadata (regex #"^/(private/)?etc$"))
-; https://crbug.com/508935
-; TODO(tkent): Remove this section when we drop 'results' attribute support.
-; https://crbug.com/590117
-(if (param-true? elcap-or-later)
- (allow file-read*
- (literal "/usr/lib/libcrypto.0.9.8.dylib")
- (literal "/usr/lib/libcsfde.dylib")
- (literal "/usr/lib/libcurl.4.dylib")
- (literal "/usr/lib/libCoreStorage.dylib")
- (literal "/usr/lib/libsasl2.2.dylib")
- (literal "/usr/lib/libutil.dylib")))
-
; https://crbug.com/605840
; file-read-metadata /System/Library/LinguisticData/en/US/hyphenation.dat
; for CFStringIsHyphenationAvailableForLocale and CFStringGetHyphenationLocationBeforeIndex
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.cc b/chromium/content/renderer/renderer_blink_platform_impl.cc
index 478cf8161ce..a3878139660 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.cc
+++ b/chromium/content/renderer/renderer_blink_platform_impl.cc
@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/guid.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
@@ -43,10 +44,8 @@
#include "content/common/frame_messages.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu_process_launch_causes.h"
-#include "content/common/mime_registry_messages.h"
#include "content/common/render_process_messages.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/service_registry.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/media_stream_utils.h"
@@ -61,6 +60,7 @@
#include "content/renderer/gamepad_shared_memory_reader.h"
#include "content/renderer/media/audio_decoder.h"
#include "content/renderer/media/canvas_capture_handler.h"
+#include "content/renderer/media/html_audio_element_capturer_source.h"
#include "content/renderer/media/html_video_element_capturer_source.h"
#include "content/renderer/media/image_capture_frame_grabber.h"
#include "content/renderer/media/media_recorder_handler.h"
@@ -84,6 +84,7 @@
#include "media/base/mime_util.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/filters/stream_parser_factory.h"
+#include "mojo/common/common_type_converters.h"
#include "storage/common/database/database_identifier.h"
#include "storage/common/quota/quota_types.h"
#include "third_party/WebKit/public/platform/BlameContext.h"
@@ -99,9 +100,9 @@
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/platform/mime_registry.mojom.h"
#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h"
#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceOrientationListener.h"
-#include "ui/gfx/color_profile.h"
#include "url/gurl.h"
#if defined(OS_MACOSX)
@@ -192,6 +193,9 @@ class RendererBlinkPlatformImpl::MimeRegistry
const blink::WebString& codecs) override;
blink::WebString mimeTypeForExtension(
const blink::WebString& file_extension) override;
+
+ private:
+ blink::mojom::MimeRegistryPtr mime_registry_;
};
class RendererBlinkPlatformImpl::FileUtilities : public WebFileUtilitiesImpl {
@@ -238,7 +242,7 @@ class RendererBlinkPlatformImpl::SandboxSupport
RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
scheduler::RendererScheduler* renderer_scheduler,
- base::WeakPtr<ServiceRegistry> service_registry)
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces)
: BlinkPlatformImpl(renderer_scheduler->DefaultTaskRunner()),
main_thread_(renderer_scheduler->CreateMainThread()),
clipboard_delegate_(new RendererClipboardDelegate),
@@ -250,7 +254,8 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
loading_task_runner_(renderer_scheduler->LoadingTaskRunner()),
web_scrollbar_behavior_(new WebScrollbarBehaviorImpl),
renderer_scheduler_(renderer_scheduler),
- blink_service_registry_(new BlinkServiceRegistryImpl(service_registry)) {
+ blink_service_registry_(
+ new BlinkServiceRegistryImpl(remote_interfaces)) {
#if !defined(OS_ANDROID) && !defined(OS_WIN)
if (g_sandbox_enabled && sandboxEnabled()) {
sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport);
@@ -511,11 +516,15 @@ WebString RendererBlinkPlatformImpl::MimeRegistry::mimeTypeForExtension(
const WebString& file_extension) {
// The sandbox restricts our access to the registry, so we need to proxy
// these calls over to the browser process.
- std::string mime_type;
- RenderThread::Get()->Send(
- new MimeRegistryMsg_GetMimeTypeFromExtension(
- blink::WebStringToFilePath(file_extension).value(), &mime_type));
- return base::ASCIIToUTF16(mime_type);
+ if (!mime_registry_)
+ RenderThread::Get()->GetRemoteInterfaces()->GetInterface(&mime_registry_);
+
+ mojo::String mime_type;
+ if (!mime_registry_->GetMimeTypeFromExtension(
+ mojo::String::From(base::string16(file_extension)), &mime_type)) {
+ return WebString();
+ }
+ return base::ASCIIToUTF16(mime_type.get());
}
//------------------------------------------------------------------------------
@@ -639,11 +648,8 @@ long long RendererBlinkPlatformImpl::databaseGetFileSize(
long long RendererBlinkPlatformImpl::databaseGetSpaceAvailableForOrigin(
const blink::WebSecurityOrigin& origin) {
- // TODO(jsbell): Pass url::Origin over IPC instead of database
- // identifier/GURL. https://crbug.com/591482
- return DatabaseUtil::DatabaseGetSpaceAvailable(WebString::fromUTF8(
- storage::GetIdentifierFromOrigin(WebSecurityOriginToGURL(origin))),
- sync_message_filter_.get());
+ return DatabaseUtil::DatabaseGetSpaceAvailable(origin,
+ sync_message_filter_.get());
}
bool RendererBlinkPlatformImpl::databaseSetFileSize(
@@ -836,27 +842,6 @@ blink::WebString RendererBlinkPlatformImpl::signedPublicKeyAndChallengeString(
//------------------------------------------------------------------------------
-void RendererBlinkPlatformImpl::screenColorProfile(
- WebVector<char>* to_profile) {
-#if defined(OS_WIN)
- // On Windows screen color profile is only available in the browser.
- std::vector<char> profile;
- // This Send() can be called from any impl-side thread. Use a thread
- // safe send to avoid crashing trying to access RenderThread::Get(),
- // which is not accessible from arbitrary threads.
- thread_safe_sender_->Send(
- new RenderProcessHostMsg_GetMonitorColorProfile(&profile));
- *to_profile = profile;
-#else
- // On other platforms, the primary monitor color profile can be read
- // directly.
- gfx::ColorProfile profile;
- *to_profile = profile.profile();
-#endif
-}
-
-//------------------------------------------------------------------------------
-
blink::WebScrollbarBehavior* RendererBlinkPlatformImpl::scrollbarBehavior() {
return web_scrollbar_behavior_.get();
}
@@ -975,6 +960,33 @@ void RendererBlinkPlatformImpl::createHTMLVideoElementCapturer(
#endif
}
+void RendererBlinkPlatformImpl::createHTMLAudioElementCapturer(
+ WebMediaStream* web_media_stream,
+ WebMediaPlayer* web_media_player) {
+ DCHECK(web_media_stream);
+ DCHECK(web_media_player);
+
+ blink::WebMediaStreamSource web_media_stream_source;
+ blink::WebMediaStreamTrack web_media_stream_track;
+ const WebString track_id = WebString::fromUTF8(base::GenerateGUID());
+
+ web_media_stream_source.initialize(track_id,
+ blink::WebMediaStreamSource::TypeAudio,
+ track_id,
+ false /* is_remote */);
+ web_media_stream_track.initialize(web_media_stream_source);
+
+ MediaStreamAudioSource* const media_stream_source =
+ HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl(
+ web_media_player);
+
+ // Takes ownership of |media_stream_source|.
+ web_media_stream_source.setExtraData(media_stream_source);
+
+ media_stream_source->ConnectToTrack(web_media_stream_track);
+ web_media_stream->addTrack(web_media_stream_track);
+}
+
//------------------------------------------------------------------------------
WebImageCaptureFrameGrabber*
@@ -1072,6 +1084,8 @@ RendererBlinkPlatformImpl::createOffscreenGraphicsContext3DProvider(
attributes.samples = 0;
attributes.sample_buffers = 0;
attributes.bind_generates_resource = false;
+ // Prefer discrete GPU for WebGL.
+ attributes.gpu_preference = gl::PreferDiscreteGpu;
attributes.fail_if_major_perf_caveat =
web_attributes.failIfMajorPerformanceCaveat;
@@ -1084,15 +1098,13 @@ RendererBlinkPlatformImpl::createOffscreenGraphicsContext3DProvider(
constexpr bool automatic_flushes = true;
constexpr bool support_locking = false;
- // Prefer discrete GPU for WebGL.
- constexpr gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
scoped_refptr<ContextProviderCommandBuffer> provider(
new ContextProviderCommandBuffer(
std::move(gpu_channel_host), gpu::GPU_STREAM_DEFAULT,
gpu::GpuStreamPriority::NORMAL, gpu::kNullSurfaceHandle,
- GURL(top_document_web_url), gpu_preference, automatic_flushes,
- support_locking, gpu::SharedMemoryLimits(), attributes, share_context,
+ GURL(top_document_web_url), automatic_flushes, support_locking,
+ gpu::SharedMemoryLimits(), attributes, share_context,
command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_WEBGL));
return new WebGraphicsContext3DProviderImpl(std::move(provider));
}
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.h b/chromium/content/renderer/renderer_blink_platform_impl.h
index 85b8fb8bab4..ac345facef6 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.h
+++ b/chromium/content/renderer/renderer_blink_platform_impl.h
@@ -48,6 +48,10 @@ class RendererScheduler;
class WebThreadImplForRendererScheduler;
}
+namespace shell {
+class InterfaceProvider;
+}
+
namespace content {
class BlinkServiceRegistryImpl;
class DeviceLightEventPump;
@@ -58,7 +62,6 @@ class PlatformEventObserverBase;
class QuotaMessageFilter;
class RendererClipboardDelegate;
class RenderView;
-class ServiceRegistry;
class ThreadSafeSender;
class WebClipboardImpl;
class WebDatabaseObserverImpl;
@@ -66,8 +69,9 @@ class WebFileSystemImpl;
class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
public:
- RendererBlinkPlatformImpl(scheduler::RendererScheduler* renderer_scheduler,
- base::WeakPtr<ServiceRegistry> service_registry);
+ RendererBlinkPlatformImpl(
+ scheduler::RendererScheduler* renderer_scheduler,
+ base::WeakPtr<shell::InterfaceProvider> remote_interfaces);
~RendererBlinkPlatformImpl() override;
// Shutdown must be called just prior to shutting down blink.
@@ -129,7 +133,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void getPluginList(bool refresh,
blink::WebPluginListBuilder* builder) override;
blink::WebPublicSuffixList* publicSuffixList() override;
- void screenColorProfile(blink::WebVector<char>* to_profile) override;
blink::WebScrollbarBehavior* scrollbarBehavior() override;
blink::WebIDBFactory* idbFactory() override;
blink::WebServiceWorkerCacheStorage* cacheStorage(
@@ -177,6 +180,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void createHTMLVideoElementCapturer(
blink::WebMediaStream* web_media_stream,
blink::WebMediaPlayer* web_media_player) override;
+ void createHTMLAudioElementCapturer(
+ blink::WebMediaStream* web_media_stream,
+ blink::WebMediaPlayer* web_media_player) override;
blink::WebImageCaptureFrameGrabber* createImageCaptureFrameGrabber() override;
blink::WebGraphicsContext3DProvider* createOffscreenGraphicsContext3DProvider(
const blink::Platform::ContextAttributes& attributes,
diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc
index a00d117ce0c..149c18f8c68 100644
--- a/chromium/content/renderer/renderer_main.cc
+++ b/chromium/content/renderer/renderer_main.cc
@@ -52,7 +52,7 @@
#endif
#if defined(ENABLE_WEBRTC)
-#include "third_party/libjingle/overrides/init_webrtc.h"
+#include "third_party/webrtc_overrides/init_webrtc.h"
#endif
#if defined(USE_OZONE)
@@ -91,8 +91,6 @@ int RendererMain(const MainFunctionParams& parameters) {
const base::CommandLine& parsed_command_line = parameters.command_line;
- MojoShellConnectionImpl::Create();
-
#if defined(OS_MACOSX)
base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool;
#endif // OS_MACOSX
@@ -200,8 +198,6 @@ int RendererMain(const MainFunctionParams& parameters) {
TRACE_EVENT_ASYNC_END0("toplevel", "RendererMain.START_MSG_LOOP", 0);
}
- MojoShellConnectionImpl::Destroy();
-
#if defined(LEAK_SANITIZER)
// Run leak detection before RenderProcessImpl goes out of scope. This helps
// ignore shutdown-only leaks.
diff --git a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
index f0060ef0b21..5f2071d3779 100644
--- a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
+++ b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
@@ -31,6 +31,10 @@ bool ScreenOrientationDispatcher::OnMessageReceived(
return handled;
}
+void ScreenOrientationDispatcher::OnDestruct() {
+ delete this;
+}
+
void ScreenOrientationDispatcher::OnLockSuccess(int request_id) {
blink::WebLockOrientationCallback* callback =
pending_callbacks_.Lookup(request_id);
diff --git a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.h b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.h
index 4eadeb191fe..9d108d27668 100644
--- a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.h
+++ b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher.h
@@ -34,6 +34,7 @@ class CONTENT_EXPORT ScreenOrientationDispatcher :
// RenderFrameObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
// blink::WebScreenOrientationClient implementation.
void lockOrientation(blink::WebScreenOrientationLockType orientation,
diff --git a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
index 4d9cf0226d2..b5f7bebf0ef 100644
--- a/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
+++ b/chromium/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
@@ -6,6 +6,7 @@
#include <list>
#include <memory>
+#include <tuple>
#include "base/logging.h"
#include "content/common/screen_orientation_messages.h"
@@ -72,9 +73,9 @@ class ScreenOrientationDispatcherTest : public testing::Test {
ScreenOrientationHostMsg_LockRequest::ID);
EXPECT_TRUE(msg != NULL);
- base::Tuple<blink::WebScreenOrientationLockType, int> params;
+ std::tuple<blink::WebScreenOrientationLockType, int> params;
ScreenOrientationHostMsg_LockRequest::Read(msg, &params);
- return base::get<1>(params);
+ return std::get<1>(params);
}
IPC::TestSink& sink() {
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client.cc b/chromium/content/renderer/service_worker/service_worker_context_client.cc
index 6a5cd56673c..c765667871b 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.cc
@@ -29,7 +29,6 @@
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/devtools_messages.h"
#include "content/common/message_port_messages.h"
-#include "content/common/mojo/service_registry_impl.h"
#include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/public/common/push_event_payload.h"
@@ -43,6 +42,7 @@
#include "content/renderer/service_worker/service_worker_type_util.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebMessagePortChannel.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
@@ -99,6 +99,9 @@ class WebServiceWorkerNetworkProviderImpl
std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData);
extra_data->set_service_worker_provider_id(provider->provider_id());
extra_data->set_originated_from_service_worker(true);
+ // Service workers are only available in secure contexts, so all requests
+ // are initiated in a secure context.
+ extra_data->set_initiated_in_secure_context(true);
request.setExtraData(extra_data.release());
}
};
@@ -171,11 +174,13 @@ struct ServiceWorkerContextClient::WorkerContextData {
using SkipWaitingCallbacksMap =
IDMap<blink::WebServiceWorkerSkipWaitingCallbacks, IDMapOwnPointer>;
using SyncEventCallbacksMap =
- IDMap<const mojo::Callback<void(blink::mojom::ServiceWorkerEventStatus)>,
+ IDMap<const base::Callback<void(blink::mojom::ServiceWorkerEventStatus)>,
IDMapOwnPointer>;
explicit WorkerContextData(ServiceWorkerContextClient* owner)
- : weak_factory(owner), proxy_weak_factory(owner->proxy_) {}
+ : interface_registry(nullptr),
+ weak_factory(owner),
+ proxy_weak_factory(owner->proxy_) {}
~WorkerContextData() {
DCHECK(thread_checker.CalledOnValidThread());
@@ -196,7 +201,8 @@ struct ServiceWorkerContextClient::WorkerContextData {
// Pending callbacks for Background Sync Events
SyncEventCallbacksMap sync_event_callbacks;
- ServiceRegistryImpl service_registry;
+ shell::InterfaceRegistry interface_registry;
+ shell::InterfaceProvider remote_interfaces;
base::ThreadChecker thread_checker;
base::WeakPtrFactory<ServiceWorkerContextClient> weak_factory;
@@ -272,12 +278,11 @@ void ServiceWorkerContextClient::OnMessageReceived(
DCHECK(handled);
}
-void ServiceWorkerContextClient::BindServiceRegistry(
- shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services) {
- context_->service_registry.Bind(std::move(services));
- context_->service_registry.BindRemoteServiceProvider(
- std::move(exposed_services));
+void ServiceWorkerContextClient::BindInterfaceProviders(
+ shell::mojom::InterfaceProviderRequest request,
+ shell::mojom::InterfaceProviderPtr remote_interfaces) {
+ context_->interface_registry.Bind(std::move(request));
+ context_->remote_interfaces.Bind(std::move(remote_interfaces));
}
blink::WebURL ServiceWorkerContextClient::scope() const {
@@ -375,8 +380,8 @@ void ServiceWorkerContextClient::workerContextStarted(
DCHECK_NE(registration_info.registration_id,
kInvalidServiceWorkerRegistrationId);
- // Register Mojo services.
- context_->service_registry.ServiceRegistry::AddService(
+ // Register Mojo interfaces.
+ context_->interface_registry.AddInterface(
base::Bind(&BackgroundSyncClientImpl::Create));
SetRegistrationInServiceWorkerGlobalScope(registration_info, version_attrs);
@@ -408,7 +413,8 @@ void ServiceWorkerContextClient::didInitializeWorkerContext(
v8::Local<v8::Context> context) {
GetContentClient()
->renderer()
- ->DidInitializeServiceWorkerContextOnWorkerThread(context, script_url_);
+ ->DidInitializeServiceWorkerContextOnWorkerThread(
+ context, embedded_worker_id_, script_url_);
}
void ServiceWorkerContextClient::willDestroyWorkerContext(
@@ -427,7 +433,7 @@ void ServiceWorkerContextClient::willDestroyWorkerContext(
g_worker_client_tls.Pointer()->Set(NULL);
GetContentClient()->renderer()->WillDestroyServiceWorkerContextOnWorkerThread(
- context, script_url_);
+ context, embedded_worker_id_, script_url_);
}
void ServiceWorkerContextClient::workerContextDestroyed() {
@@ -501,21 +507,23 @@ void ServiceWorkerContextClient::didHandleInstallEvent(
int request_id,
blink::WebServiceWorkerEventResult result) {
Send(new ServiceWorkerHostMsg_InstallEventFinished(
- GetRoutingID(), request_id, result));
+ GetRoutingID(), request_id, result, proxy_->hasFetchEventHandler()));
}
-void ServiceWorkerContextClient::didHandleFetchEvent(int request_id) {
- Send(new ServiceWorkerHostMsg_FetchEventFinished(
- GetRoutingID(), request_id,
- SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
+void ServiceWorkerContextClient::respondToFetchEvent(int response_id) {
+ Send(new ServiceWorkerHostMsg_FetchEventResponse(
+ GetRoutingID(), response_id, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
ServiceWorkerResponse()));
}
-void ServiceWorkerContextClient::didHandleFetchEvent(
- int request_id,
+void ServiceWorkerContextClient::respondToFetchEvent(
+ int response_id,
const blink::WebServiceWorkerResponse& web_response) {
ServiceWorkerHeaderMap headers;
GetServiceWorkerHeaderMapFromWebResponse(web_response, &headers);
+ ServiceWorkerHeaderList cors_exposed_header_names;
+ GetCorsExposedHeaderNamesFromWebResponse(web_response,
+ &cors_exposed_header_names);
ServiceWorkerResponse response(
web_response.url(), web_response.status(),
web_response.statusText().utf8(), web_response.responseType(), headers,
@@ -523,13 +531,19 @@ void ServiceWorkerContextClient::didHandleFetchEvent(
web_response.streamURL(), web_response.error(),
base::Time::FromInternalValue(web_response.responseTime()),
!web_response.cacheStorageCacheName().isNull(),
- web_response.cacheStorageCacheName().utf8());
- Send(new ServiceWorkerHostMsg_FetchEventFinished(
- GetRoutingID(), request_id,
- SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
+ web_response.cacheStorageCacheName().utf8(), cors_exposed_header_names);
+ Send(new ServiceWorkerHostMsg_FetchEventResponse(
+ GetRoutingID(), response_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE,
response));
}
+void ServiceWorkerContextClient::didHandleFetchEvent(
+ int event_finish_id,
+ blink::WebServiceWorkerEventResult result) {
+ Send(new ServiceWorkerHostMsg_FetchEventFinished(GetRoutingID(),
+ event_finish_id, result));
+}
+
void ServiceWorkerContextClient::didHandleNotificationClickEvent(
int request_id,
blink::WebServiceWorkerEventResult result) {
@@ -580,7 +594,8 @@ ServiceWorkerContextClient::createServiceWorkerNetworkProvider(
provider_context_ = provider->context();
// Tell the network provider about which version to load.
- provider->SetServiceWorkerVersionId(service_worker_version_id_);
+ provider->SetServiceWorkerVersionId(service_worker_version_id_,
+ embedded_worker_id_);
// The provider is kept around for the lifetime of the DataSource
// and ownership is transferred to the DataSource.
@@ -758,7 +773,8 @@ void ServiceWorkerContextClient::OnInstallEvent(int request_id) {
}
void ServiceWorkerContextClient::OnFetchEvent(
- int request_id,
+ int response_id,
+ int event_finish_id,
const ServiceWorkerFetchRequest& request) {
blink::WebServiceWorkerRequest webRequest;
TRACE_EVENT0("ServiceWorker",
@@ -789,9 +805,9 @@ void ServiceWorkerContextClient::OnFetchEvent(
webRequest.setClientId(blink::WebString::fromUTF8(request.client_id));
webRequest.setIsReload(request.is_reload);
if (request.fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) {
- proxy_->dispatchForeignFetchEvent(request_id, webRequest);
+ proxy_->dispatchForeignFetchEvent(response_id, event_finish_id, webRequest);
} else {
- proxy_->dispatchFetchEvent(request_id, webRequest);
+ proxy_->dispatchFetchEvent(response_id, event_finish_id, webRequest);
}
}
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client.h b/chromium/content/renderer/service_worker/service_worker_context_client.h
index 48b4dbd5178..a009d30c492 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.h
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.h
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include "base/callback.h"
#include "base/id_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -64,7 +65,7 @@ class ServiceWorkerContextClient
: public blink::WebServiceWorkerContextClient {
public:
using SyncCallback =
- mojo::Callback<void(blink::mojom::ServiceWorkerEventStatus)>;
+ base::Callback<void(blink::mojom::ServiceWorkerEventStatus)>;
// Returns a thread-specific client instance. This does NOT create a
// new instance.
@@ -82,11 +83,10 @@ class ServiceWorkerContextClient
int embedded_worker_id,
const IPC::Message& message);
- // Called some time after the worker has started. Attempts to use the
- // ServiceRegistry to connect to services before this method is called are
- // queued up and will resolve after this method is called.
- void BindServiceRegistry(shell::mojom::InterfaceProviderRequest services,
- shell::mojom::InterfaceProviderPtr exposed_services);
+ // Called some time after the worker has started.
+ void BindInterfaceProviders(
+ shell::mojom::InterfaceProviderRequest request,
+ shell::mojom::InterfaceProviderPtr remote_interfaces);
// WebServiceWorkerContextClient overrides.
blink::WebURL scope() const override;
@@ -136,10 +136,12 @@ class ServiceWorkerContextClient
void didHandleInstallEvent(
int request_id,
blink::WebServiceWorkerEventResult result) override;
- void didHandleFetchEvent(int request_id) override;
- void didHandleFetchEvent(
- int request_id,
+ void respondToFetchEvent(int response_id) override;
+ void respondToFetchEvent(
+ int response_id,
const blink::WebServiceWorkerResponse& response) override;
+ void didHandleFetchEvent(int event_finish_id,
+ blink::WebServiceWorkerEventResult result) override;
void didHandleNotificationClickEvent(
int request_id,
blink::WebServiceWorkerEventResult result) override;
@@ -199,7 +201,9 @@ class ServiceWorkerContextClient
int request_id,
const ServiceWorkerMsg_ExtendableMessageEvent_Params& params);
void OnInstallEvent(int request_id);
- void OnFetchEvent(int request_id, const ServiceWorkerFetchRequest& request);
+ void OnFetchEvent(int response_id,
+ int event_finish_id,
+ const ServiceWorkerFetchRequest& request);
void OnNotificationClickEvent(
int request_id,
int64_t persistent_notification_id,
diff --git a/chromium/content/renderer/service_worker/service_worker_type_util.cc b/chromium/content/renderer/service_worker/service_worker_type_util.cc
index 9eb9f9c6c53..35769afd267 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_util.cc
+++ b/chromium/content/renderer/service_worker/service_worker_type_util.cc
@@ -61,4 +61,14 @@ void GetServiceWorkerHeaderMapFromWebResponse(
web_response.visitHTTPHeaderFields(MakeHeaderVisitor(headers).get());
}
+void GetCorsExposedHeaderNamesFromWebResponse(
+ const blink::WebServiceWorkerResponse& web_response,
+ ServiceWorkerHeaderList* result) {
+ blink::WebVector<blink::WebString> headers =
+ web_response.corsExposedHeaderNames();
+ result->resize(headers.size());
+ std::transform(headers.begin(), headers.end(), result->begin(),
+ [](const blink::WebString& s) { return s.latin1(); });
+}
+
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_type_util.h b/chromium/content/renderer/service_worker/service_worker_type_util.h
index 439231fdebd..f1cfa84e7a3 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_util.h
+++ b/chromium/content/renderer/service_worker/service_worker_type_util.h
@@ -22,6 +22,10 @@ void GetServiceWorkerHeaderMapFromWebResponse(
const blink::WebServiceWorkerResponse& web_response,
ServiceWorkerHeaderMap* headers);
+void GetCorsExposedHeaderNamesFromWebResponse(
+ const blink::WebServiceWorkerResponse& web_response,
+ ServiceWorkerHeaderList* result);
+
} // namespace content
#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_UTIL_H_
diff --git a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index 4b7509754fc..1b58b4f59dd 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -18,6 +18,7 @@
#include "content/child/shared_worker_devtools_agent.h"
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/worker_messages.h"
+#include "content/public/common/origin_util.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.h"
@@ -72,6 +73,7 @@ class DataSourceExtraData
public:
DataSourceExtraData() {}
~DataSourceExtraData() override {}
+ bool is_secure_context = false;
};
// Called on the main thread only and blink owns it.
@@ -86,13 +88,19 @@ class WebServiceWorkerNetworkProviderImpl
GetNetworkProviderFromDataSource(data_source);
std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData);
extra_data->set_service_worker_provider_id(provider->provider_id());
+ extra_data->set_initiated_in_secure_context(
+ static_cast<DataSourceExtraData*>(data_source->getExtraData())
+ ->is_secure_context);
request.setExtraData(extra_data.release());
// Explicitly set the SkipServiceWorker flag for subresources here if the
// renderer process hasn't received SetControllerServiceWorker message.
if (request.getRequestContext() !=
blink::WebURLRequest::RequestContextSharedWorker &&
- !provider->IsControlledByServiceWorker()) {
- request.setSkipServiceWorker(true);
+ !provider->IsControlledByServiceWorker() &&
+ request.skipServiceWorker() !=
+ blink::WebURLRequest::SkipServiceWorker::All) {
+ request.setSkipServiceWorker(
+ blink::WebURLRequest::SkipServiceWorker::Controlling);
}
}
@@ -248,6 +256,7 @@ EmbeddedSharedWorkerStub::createServiceWorkerNetworkProvider(
// The provider is kept around for the lifetime of the DataSource
// and ownership is transferred to the DataSource.
DataSourceExtraData* extra_data = new DataSourceExtraData();
+ extra_data->is_secure_context = IsOriginSecure(url_);
data_source->setExtraData(extra_data);
ServiceWorkerNetworkProvider::AttachToDocumentState(extra_data,
std::move(provider));
diff --git a/chromium/content/renderer/shared_worker_repository.cc b/chromium/content/renderer/shared_worker_repository.cc
index 607e044fe27..466a79b6877 100644
--- a/chromium/content/renderer/shared_worker_repository.cc
+++ b/chromium/content/renderer/shared_worker_repository.cc
@@ -59,4 +59,8 @@ void SharedWorkerRepository::documentDetached(DocumentID document) {
}
}
+void SharedWorkerRepository::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/shared_worker_repository.h b/chromium/content/renderer/shared_worker_repository.h
index 93ac628c379..8714f3af39d 100644
--- a/chromium/content/renderer/shared_worker_repository.h
+++ b/chromium/content/renderer/shared_worker_repository.h
@@ -37,6 +37,9 @@ class SharedWorkerRepository : public RenderFrameObserver,
void documentDetached(DocumentID document_id) override;
private:
+ // RenderFrameObserver implementation.
+ void OnDestruct() override;
+
std::set<DocumentID> documents_with_workers_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerRepository);
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.cc b/chromium/content/renderer/speech_recognition_dispatcher.cc
index 585b61cd8da..e707f4105df 100644
--- a/chromium/content/renderer/speech_recognition_dispatcher.cc
+++ b/chromium/content/renderer/speech_recognition_dispatcher.cc
@@ -66,6 +66,10 @@ bool SpeechRecognitionDispatcher::OnMessageReceived(
return handled;
}
+void SpeechRecognitionDispatcher::OnDestruct() {
+ delete this;
+}
+
void SpeechRecognitionDispatcher::start(
const WebSpeechRecognitionHandle& handle,
const WebSpeechRecognitionParams& params,
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.h b/chromium/content/renderer/speech_recognition_dispatcher.h
index bde0bdf0f33..d0cddc075ea 100644
--- a/chromium/content/renderer/speech_recognition_dispatcher.h
+++ b/chromium/content/renderer/speech_recognition_dispatcher.h
@@ -45,6 +45,7 @@ class SpeechRecognitionDispatcher : public RenderViewObserver,
private:
// RenderViewObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
// blink::WebSpeechRecognizer implementation.
void start(const blink::WebSpeechRecognitionHandle&,
diff --git a/chromium/content/renderer/stats_collection_observer.cc b/chromium/content/renderer/stats_collection_observer.cc
index 4c4b911ec8c..f2c45bf461c 100644
--- a/chromium/content/renderer/stats_collection_observer.cc
+++ b/chromium/content/renderer/stats_collection_observer.cc
@@ -30,4 +30,8 @@ void StatsCollectionObserver::DidStopLoading() {
impl->RemoveObserver(this);
}
+void StatsCollectionObserver::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/stats_collection_observer.h b/chromium/content/renderer/stats_collection_observer.h
index 5a17dfe6933..e1b73233120 100644
--- a/chromium/content/renderer/stats_collection_observer.h
+++ b/chromium/content/renderer/stats_collection_observer.h
@@ -30,6 +30,9 @@ class StatsCollectionObserver : public RenderViewObserver {
const base::Time& load_stop_time() { return stop_time_; }
private:
+ // RenderViewObserver implementation.
+ void OnDestruct() override;
+
base::Time start_time_;
base::Time stop_time_;
diff --git a/chromium/content/renderer/text_input_client_observer.cc b/chromium/content/renderer/text_input_client_observer.cc
index e3b8bd7a377..3c953eebaad 100644
--- a/chromium/content/renderer/text_input_client_observer.cc
+++ b/chromium/content/renderer/text_input_client_observer.cc
@@ -48,6 +48,10 @@ bool TextInputClientObserver::OnMessageReceived(const IPC::Message& message) {
return handled;
}
+void TextInputClientObserver::OnDestruct() {
+ delete this;
+}
+
blink::WebView* TextInputClientObserver::webview() {
return render_view()->GetWebView();
}
diff --git a/chromium/content/renderer/text_input_client_observer.h b/chromium/content/renderer/text_input_client_observer.h
index c41b670ce22..2c538a61c2b 100644
--- a/chromium/content/renderer/text_input_client_observer.h
+++ b/chromium/content/renderer/text_input_client_observer.h
@@ -31,6 +31,9 @@ class TextInputClientObserver : public RenderViewObserver {
bool OnMessageReceived(const IPC::Message& message) override;
private:
+ // RenderViewObserver implementation.
+ void OnDestruct() override;
+
// Returns the WebView of the RenderView.
blink::WebView* webview();
diff --git a/chromium/content/renderer/visual_state_browsertest.cc b/chromium/content/renderer/visual_state_browsertest.cc
index 26d9a6ddd26..2a8b49bff8f 100644
--- a/chromium/content/renderer/visual_state_browsertest.cc
+++ b/chromium/content/renderer/visual_state_browsertest.cc
@@ -50,6 +50,9 @@ class CommitObserver : public RenderViewObserver {
int GetCommitCount() { return commit_count_; }
private:
+ // RenderViewObserver implementation.
+ void OnDestruct() override { delete this; }
+
std::set<base::Closure*> quit_closures_;
int commit_count_;
};
diff --git a/chromium/content/renderer/web_ui_extension.cc b/chromium/content/renderer/web_ui_extension.cc
index 0751e6ee68b..a793b4e215b 100644
--- a/chromium/content/renderer/web_ui_extension.cc
+++ b/chromium/content/renderer/web_ui_extension.cc
@@ -5,6 +5,7 @@
#include "content/renderer/web_ui_extension.h"
#include <memory>
+#include <utility>
#include "base/values.h"
#include "content/common/view_messages.h"
@@ -108,13 +109,9 @@ void WebUIExtension::Send(gin::Arguments* args) {
}
std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create());
-
- base::Value* value =
- converter->FromV8Value(obj, frame->mainWorldScriptContext());
- base::ListValue* list = NULL;
- value->GetAsList(&list);
- DCHECK(list);
- content.reset(list);
+ content = base::ListValue::From(
+ converter->FromV8Value(obj, frame->mainWorldScriptContext()));
+ DCHECK(content);
}
// Send the message up to the browser.
diff --git a/chromium/content/renderer/web_ui_extension_data.cc b/chromium/content/renderer/web_ui_extension_data.cc
index 80d570fd9a1..43cf15ec347 100644
--- a/chromium/content/renderer/web_ui_extension_data.cc
+++ b/chromium/content/renderer/web_ui_extension_data.cc
@@ -39,4 +39,8 @@ void WebUIExtensionData::OnSetWebUIProperty(const std::string& name,
variable_map_[name] = value;
}
+void WebUIExtensionData::OnDestruct() {
+ delete this;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/web_ui_extension_data.h b/chromium/content/renderer/web_ui_extension_data.h
index 8bbac72a5b8..566faed6c4d 100644
--- a/chromium/content/renderer/web_ui_extension_data.h
+++ b/chromium/content/renderer/web_ui_extension_data.h
@@ -28,6 +28,7 @@ class WebUIExtensionData
private:
// RenderViewObserver implementation.
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnDestruct() override;
void OnSetWebUIProperty(const std::string& name, const std::string& value);