From 21d179b334e59e9a3bfcaed4c4430bef1bc5759d Mon Sep 17 00:00:00 2001 From: Kristian Monsen Date: Wed, 11 May 2011 20:53:37 +0100 Subject: Merge Chromium at 10.0.621.0: Initial merge by git. Change-Id: I070cc91c608dfa4a968a5a54c173260765ac8097 --- webkit/glue/bookmarklet_unittest.cc | 18 +- webkit/glue/context_menu.cc | 2 +- webkit/glue/context_menu.h | 4 +- webkit/glue/cpp_bound_class.cc | 4 +- webkit/glue/cpp_bound_class.h | 3 +- webkit/glue/cpp_bound_class_unittest.cc | 11 +- webkit/glue/cpp_variant.cc | 9 +- webkit/glue/cpp_variant.h | 2 +- webkit/glue/glue_serialize.cc | 38 +- webkit/glue/media/audio_decoder.cc | 76 ++ webkit/glue/media/audio_decoder.h | 20 + webkit/glue/media/buffered_data_source.cc | 590 +------- webkit/glue/media/buffered_data_source.h | 219 +-- webkit/glue/media/buffered_data_source_unittest.cc | 548 +------- webkit/glue/media/buffered_resource_loader.cc | 578 ++++++++ webkit/glue/media/buffered_resource_loader.h | 246 ++++ .../media/buffered_resource_loader_unittest.cc | 486 +++++++ .../media/media_resource_loader_bridge_factory.cc | 82 -- .../media/media_resource_loader_bridge_factory.h | 76 -- ...edia_resource_loader_bridge_factory_unittest.cc | 44 - .../mock_media_resource_loader_bridge_factory.h | 36 - webkit/glue/media/simple_data_source.cc | 142 +- webkit/glue/media/simple_data_source.h | 76 +- webkit/glue/media/simple_data_source_unittest.cc | 95 +- webkit/glue/mimetype_unittest.cc | 12 +- webkit/glue/mock_resource_loader_bridge.h | 44 - webkit/glue/multipart_response_delegate.cc | 44 +- webkit/glue/multipart_response_delegate.h | 3 +- .../glue/multipart_response_delegate_unittest.cc | 16 +- webkit/glue/plugins/DEPS | 4 - .../plugins/carbon_plugin_window_tracker_mac.cc | 55 - .../plugins/carbon_plugin_window_tracker_mac.h | 53 - .../plugins/coregraphics_private_symbols_mac.h | 27 - webkit/glue/plugins/default_plugin_shared.h | 31 - webkit/glue/plugins/gtk_plugin_container.cc | 85 -- webkit/glue/plugins/gtk_plugin_container.h | 26 - .../glue/plugins/gtk_plugin_container_manager.cc | 155 --- webkit/glue/plugins/gtk_plugin_container_manager.h | 57 - webkit/glue/plugins/npapi_extension_thunk.cc | 551 -------- webkit/glue/plugins/npapi_extension_thunk.h | 23 - webkit/glue/plugins/pepper_audio.cc | 389 ------ webkit/glue/plugins/pepper_audio.h | 136 -- webkit/glue/plugins/pepper_buffer.cc | 117 -- webkit/glue/plugins/pepper_buffer.h | 56 - webkit/glue/plugins/pepper_char_set.cc | 166 --- webkit/glue/plugins/pepper_char_set.h | 21 - webkit/glue/plugins/pepper_class.h | 66 - webkit/glue/plugins/pepper_common.h | 24 - webkit/glue/plugins/pepper_cursor_control.cc | 92 -- webkit/glue/plugins/pepper_cursor_control.h | 19 - webkit/glue/plugins/pepper_dir_contents.h | 18 - webkit/glue/plugins/pepper_directory_reader.cc | 156 --- webkit/glue/plugins/pepper_directory_reader.h | 51 - webkit/glue/plugins/pepper_error_util.cc | 33 - webkit/glue/plugins/pepper_error_util.h | 16 - webkit/glue/plugins/pepper_event_conversion.cc | 301 ----- webkit/glue/plugins/pepper_event_conversion.h | 30 - webkit/glue/plugins/pepper_file_callbacks.cc | 99 -- webkit/glue/plugins/pepper_file_callbacks.h | 57 - webkit/glue/plugins/pepper_file_chooser.cc | 161 --- webkit/glue/plugins/pepper_file_chooser.h | 52 - webkit/glue/plugins/pepper_file_io.cc | 433 ------ webkit/glue/plugins/pepper_file_io.h | 94 -- webkit/glue/plugins/pepper_file_ref.cc | 343 ----- webkit/glue/plugins/pepper_file_ref.h | 62 - webkit/glue/plugins/pepper_file_system.cc | 85 -- webkit/glue/plugins/pepper_file_system.h | 44 - webkit/glue/plugins/pepper_font.cc | 294 ---- webkit/glue/plugins/pepper_font.h | 53 - webkit/glue/plugins/pepper_fullscreen_container.h | 36 - webkit/glue/plugins/pepper_graphics_2d.cc | 638 --------- webkit/glue/plugins/pepper_graphics_2d.h | 180 --- webkit/glue/plugins/pepper_graphics_3d.cc | 256 ---- webkit/glue/plugins/pepper_graphics_3d.h | 90 -- webkit/glue/plugins/pepper_graphics_3d_gl.cc | 671 ---------- webkit/glue/plugins/pepper_image_data.cc | 210 --- webkit/glue/plugins/pepper_image_data.h | 131 -- webkit/glue/plugins/pepper_plugin_delegate.h | 281 ---- webkit/glue/plugins/pepper_plugin_instance.cc | 1179 ---------------- webkit/glue/plugins/pepper_plugin_instance.h | 318 ----- webkit/glue/plugins/pepper_plugin_module.cc | 553 -------- webkit/glue/plugins/pepper_plugin_module.h | 169 --- webkit/glue/plugins/pepper_plugin_object.cc | 887 ------------ webkit/glue/plugins/pepper_plugin_object.h | 89 -- webkit/glue/plugins/pepper_private.cc | 302 ----- webkit/glue/plugins/pepper_private.h | 23 - webkit/glue/plugins/pepper_private2.cc | 243 ---- webkit/glue/plugins/pepper_private2.h | 42 - webkit/glue/plugins/pepper_private2_linux.cc | 110 -- webkit/glue/plugins/pepper_resource.cc | 37 - webkit/glue/plugins/pepper_resource.h | 140 -- webkit/glue/plugins/pepper_resource_tracker.cc | 167 --- webkit/glue/plugins/pepper_resource_tracker.h | 134 -- webkit/glue/plugins/pepper_scrollbar.cc | 242 ---- webkit/glue/plugins/pepper_scrollbar.h | 62 - webkit/glue/plugins/pepper_string.cc | 13 - webkit/glue/plugins/pepper_string.h | 30 - webkit/glue/plugins/pepper_transport.cc | 140 -- webkit/glue/plugins/pepper_transport.h | 35 - webkit/glue/plugins/pepper_url_loader.cc | 532 -------- webkit/glue/plugins/pepper_url_loader.h | 140 -- webkit/glue/plugins/pepper_url_request_info.cc | 278 ---- webkit/glue/plugins/pepper_url_request_info.h | 69 - webkit/glue/plugins/pepper_url_response_info.cc | 137 -- webkit/glue/plugins/pepper_url_response_info.h | 51 - webkit/glue/plugins/pepper_url_util.cc | 177 --- webkit/glue/plugins/pepper_url_util.h | 19 - webkit/glue/plugins/pepper_var.cc | 853 ------------ webkit/glue/plugins/pepper_var.h | 251 ---- webkit/glue/plugins/pepper_video_decoder.cc | 141 -- webkit/glue/plugins/pepper_video_decoder.h | 50 - webkit/glue/plugins/pepper_webplugin_impl.cc | 226 ---- webkit/glue/plugins/pepper_webplugin_impl.h | 95 -- webkit/glue/plugins/pepper_widget.cc | 95 -- webkit/glue/plugins/pepper_widget.h | 53 - webkit/glue/plugins/plugin_constants_win.h | 41 - webkit/glue/plugins/plugin_group.cc | 419 ------ webkit/glue/plugins/plugin_group.h | 184 --- webkit/glue/plugins/plugin_group_unittest.cc | 181 --- webkit/glue/plugins/plugin_host.cc | 1104 --------------- webkit/glue/plugins/plugin_host.h | 63 - webkit/glue/plugins/plugin_instance.cc | 680 ---------- webkit/glue/plugins/plugin_instance.h | 375 ------ webkit/glue/plugins/plugin_instance_mac.mm | 133 -- webkit/glue/plugins/plugin_lib.cc | 349 ----- webkit/glue/plugins/plugin_lib.h | 120 -- webkit/glue/plugins/plugin_lib_mac.mm | 348 ----- webkit/glue/plugins/plugin_lib_posix.cc | 256 ---- webkit/glue/plugins/plugin_lib_unittest.cc | 152 --- webkit/glue/plugins/plugin_lib_win.cc | 46 - webkit/glue/plugins/plugin_list.cc | 613 --------- webkit/glue/plugins/plugin_list.h | 304 +---- webkit/glue/plugins/plugin_list_mac.mm | 103 -- webkit/glue/plugins/plugin_list_posix.cc | 270 ---- webkit/glue/plugins/plugin_list_win.cc | 410 ------ webkit/glue/plugins/plugin_stream.cc | 254 ---- webkit/glue/plugins/plugin_stream.h | 158 --- webkit/glue/plugins/plugin_stream_posix.cc | 74 - webkit/glue/plugins/plugin_stream_url.cc | 118 -- webkit/glue/plugins/plugin_stream_url.h | 71 - webkit/glue/plugins/plugin_stream_win.cc | 97 -- webkit/glue/plugins/plugin_string_stream.cc | 37 - webkit/glue/plugins/plugin_string_stream.h | 39 - webkit/glue/plugins/plugin_stubs.cc | 30 - webkit/glue/plugins/plugin_switches.cc | 15 - webkit/glue/plugins/plugin_switches.h | 15 - .../glue/plugins/plugin_web_event_converter_mac.h | 60 - .../glue/plugins/plugin_web_event_converter_mac.mm | 359 ----- webkit/glue/plugins/ppb_private.h | 135 -- webkit/glue/plugins/ppb_private2.h | 117 -- webkit/glue/plugins/ppp_private.h | 20 - .../glue/plugins/quickdraw_drawing_manager_mac.cc | 154 --- .../glue/plugins/quickdraw_drawing_manager_mac.h | 83 -- webkit/glue/plugins/test/Info.plist | 46 - webkit/glue/plugins/test/npapi_constants.cc | 10 - webkit/glue/plugins/test/npapi_constants.h | 19 - webkit/glue/plugins/test/npapi_test.cc | 122 -- webkit/glue/plugins/test/npapi_test.def | 6 - webkit/glue/plugins/test/npapi_test.rc | 102 -- webkit/glue/plugins/test/plugin_arguments_test.cc | 69 - webkit/glue/plugins/test/plugin_arguments_test.h | 43 - webkit/glue/plugins/test/plugin_client.cc | 240 ---- webkit/glue/plugins/test/plugin_client.h | 45 - .../test/plugin_create_instance_in_paint.cc | 78 -- .../plugins/test/plugin_create_instance_in_paint.h | 33 - .../test/plugin_delete_plugin_in_stream_test.cc | 45 - .../test/plugin_delete_plugin_in_stream_test.h | 30 - .../test/plugin_get_javascript_url2_test.cc | 134 -- .../plugins/test/plugin_get_javascript_url2_test.h | 38 - .../plugins/test/plugin_get_javascript_url_test.cc | 218 --- .../plugins/test/plugin_get_javascript_url_test.h | 47 - webkit/glue/plugins/test/plugin_geturl_test.cc | 414 ------ webkit/glue/plugins/test/plugin_geturl_test.h | 61 - .../plugins/test/plugin_javascript_open_popup.cc | 103 -- .../plugins/test/plugin_javascript_open_popup.h | 47 - webkit/glue/plugins/test/plugin_new_fails_test.cc | 18 - webkit/glue/plugins/test/plugin_new_fails_test.h | 21 - .../plugins/test/plugin_npobject_lifetime_test.cc | 174 --- .../plugins/test/plugin_npobject_lifetime_test.h | 82 -- .../plugins/test/plugin_npobject_proxy_test.cc | 51 - .../glue/plugins/test/plugin_npobject_proxy_test.h | 27 - webkit/glue/plugins/test/plugin_private_test.cc | 57 - webkit/glue/plugins/test/plugin_private_test.h | 25 - .../plugins/test/plugin_schedule_timer_test.cc | 116 -- .../glue/plugins/test/plugin_schedule_timer_test.h | 68 - webkit/glue/plugins/test/plugin_setup_test.cc | 22 - webkit/glue/plugins/test/plugin_setup_test.h | 24 - webkit/glue/plugins/test/plugin_test.cc | 155 --- webkit/glue/plugins/test/plugin_test.h | 134 -- webkit/glue/plugins/test/plugin_test_factory.cc | 104 -- webkit/glue/plugins/test/plugin_test_factory.h | 22 - .../plugins/test/plugin_thread_async_call_test.cc | 117 -- .../plugins/test/plugin_thread_async_call_test.h | 39 - .../glue/plugins/test/plugin_window_size_test.cc | 55 - webkit/glue/plugins/test/plugin_window_size_test.h | 24 - webkit/glue/plugins/test/plugin_windowed_test.cc | 150 --- webkit/glue/plugins/test/plugin_windowed_test.h | 33 - webkit/glue/plugins/test/plugin_windowless_test.cc | 261 ---- webkit/glue/plugins/test/plugin_windowless_test.h | 35 - webkit/glue/plugins/test/resource.h | 15 - webkit/glue/plugins/webplugin.cc | 26 - webkit/glue/plugins/webplugin.h | 200 --- webkit/glue/plugins/webplugin_2d_device_delegate.h | 57 - webkit/glue/plugins/webplugin_3d_device_delegate.h | 101 -- .../plugins/webplugin_accelerated_surface_mac.h | 44 - .../glue/plugins/webplugin_audio_device_delegate.h | 56 - webkit/glue/plugins/webplugin_delegate.h | 166 --- webkit/glue/plugins/webplugin_delegate_impl.cc | 304 ----- webkit/glue/plugins/webplugin_delegate_impl.h | 511 ------- webkit/glue/plugins/webplugin_delegate_impl_gtk.cc | 767 ----------- webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 1145 ---------------- webkit/glue/plugins/webplugin_delegate_impl_win.cc | 1410 -------------------- webkit/glue/plugins/webplugin_file_delegate.h | 35 - webkit/glue/plugins/webplugin_impl.cc | 1379 ------------------- webkit/glue/plugins/webplugin_impl.h | 332 ----- webkit/glue/plugins/webplugin_impl_unittest.cc | 232 ---- webkit/glue/plugins/webplugin_page_delegate.h | 69 - webkit/glue/plugins/webplugin_print_delegate.h | 49 - webkit/glue/plugins/webplugininfo.cc | 44 - webkit/glue/plugins/webplugininfo.h | 60 - webkit/glue/plugins/webview_plugin.cc | 217 --- webkit/glue/plugins/webview_plugin.h | 138 -- webkit/glue/resource_loader_bridge.cc | 5 +- webkit/glue/resource_loader_bridge.h | 11 +- webkit/glue/resources/webkit_strings_am.xtb | 2 +- webkit/glue/resources/webkit_strings_ar.xtb | 4 +- webkit/glue/resources/webkit_strings_bg.xtb | 4 +- webkit/glue/resources/webkit_strings_bn.xtb | 4 +- webkit/glue/resources/webkit_strings_ca.xtb | 4 +- webkit/glue/resources/webkit_strings_cs.xtb | 4 +- webkit/glue/resources/webkit_strings_da.xtb | 4 +- webkit/glue/resources/webkit_strings_de.xtb | 4 +- webkit/glue/resources/webkit_strings_el.xtb | 4 +- webkit/glue/resources/webkit_strings_en-GB.xtb | 4 +- webkit/glue/resources/webkit_strings_es-419.xtb | 4 +- webkit/glue/resources/webkit_strings_es.xtb | 4 +- webkit/glue/resources/webkit_strings_et.xtb | 4 +- webkit/glue/resources/webkit_strings_fa.xtb | 4 +- webkit/glue/resources/webkit_strings_fi.xtb | 4 +- webkit/glue/resources/webkit_strings_fil.xtb | 4 +- webkit/glue/resources/webkit_strings_fr.xtb | 4 +- webkit/glue/resources/webkit_strings_gu.xtb | 4 +- webkit/glue/resources/webkit_strings_hi.xtb | 4 +- webkit/glue/resources/webkit_strings_hr.xtb | 4 +- webkit/glue/resources/webkit_strings_hu.xtb | 4 +- webkit/glue/resources/webkit_strings_id.xtb | 4 +- webkit/glue/resources/webkit_strings_it.xtb | 4 +- webkit/glue/resources/webkit_strings_iw.xtb | 4 +- webkit/glue/resources/webkit_strings_ja.xtb | 4 +- webkit/glue/resources/webkit_strings_kn.xtb | 4 +- webkit/glue/resources/webkit_strings_ko.xtb | 4 +- webkit/glue/resources/webkit_strings_lt.xtb | 4 +- webkit/glue/resources/webkit_strings_lv.xtb | 4 +- webkit/glue/resources/webkit_strings_ml.xtb | 4 +- webkit/glue/resources/webkit_strings_mr.xtb | 4 +- webkit/glue/resources/webkit_strings_nl.xtb | 4 +- webkit/glue/resources/webkit_strings_no.xtb | 4 +- webkit/glue/resources/webkit_strings_pl.xtb | 4 +- webkit/glue/resources/webkit_strings_pt-BR.xtb | 4 +- webkit/glue/resources/webkit_strings_pt-PT.xtb | 4 +- webkit/glue/resources/webkit_strings_ro.xtb | 52 +- webkit/glue/resources/webkit_strings_ru.xtb | 4 +- webkit/glue/resources/webkit_strings_sk.xtb | 4 +- webkit/glue/resources/webkit_strings_sl.xtb | 4 +- webkit/glue/resources/webkit_strings_sr.xtb | 6 +- webkit/glue/resources/webkit_strings_sv.xtb | 4 +- webkit/glue/resources/webkit_strings_sw.xtb | 2 +- webkit/glue/resources/webkit_strings_ta.xtb | 4 +- webkit/glue/resources/webkit_strings_te.xtb | 4 +- webkit/glue/resources/webkit_strings_th.xtb | 4 +- webkit/glue/resources/webkit_strings_tr.xtb | 4 +- webkit/glue/resources/webkit_strings_uk.xtb | 4 +- webkit/glue/resources/webkit_strings_vi.xtb | 4 +- webkit/glue/resources/webkit_strings_zh-CN.xtb | 4 +- webkit/glue/resources/webkit_strings_zh-TW.xtb | 4 +- webkit/glue/webaccessibility.cc | 2 + webkit/glue/webaccessibility.h | 2 +- webkit/glue/webcursor.cc | 36 +- webkit/glue/webcursor_mac.mm | 12 +- webkit/glue/webcursor_unittest.cc | 19 +- webkit/glue/webkit_glue.cc | 96 +- webkit/glue/webkit_glue.gypi | 309 +++-- webkit/glue/webkit_glue.h | 35 +- webkit/glue/webkitclient_impl.cc | 25 +- webkit/glue/webkitclient_impl.h | 3 + webkit/glue/webmediaplayer_impl.cc | 30 +- webkit/glue/webmediaplayer_impl.h | 24 +- webkit/glue/webpreferences.cc | 24 +- webkit/glue/webpreferences.h | 14 +- webkit/glue/weburlloader_impl.cc | 29 +- 290 files changed, 2276 insertions(+), 36392 deletions(-) create mode 100644 webkit/glue/media/audio_decoder.cc create mode 100644 webkit/glue/media/audio_decoder.h create mode 100644 webkit/glue/media/buffered_resource_loader.cc create mode 100644 webkit/glue/media/buffered_resource_loader.h create mode 100644 webkit/glue/media/buffered_resource_loader_unittest.cc delete mode 100644 webkit/glue/media/media_resource_loader_bridge_factory.cc delete mode 100644 webkit/glue/media/media_resource_loader_bridge_factory.h delete mode 100644 webkit/glue/media/media_resource_loader_bridge_factory_unittest.cc delete mode 100644 webkit/glue/media/mock_media_resource_loader_bridge_factory.h delete mode 100644 webkit/glue/mock_resource_loader_bridge.h delete mode 100644 webkit/glue/plugins/DEPS delete mode 100644 webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc delete mode 100644 webkit/glue/plugins/carbon_plugin_window_tracker_mac.h delete mode 100644 webkit/glue/plugins/coregraphics_private_symbols_mac.h delete mode 100644 webkit/glue/plugins/default_plugin_shared.h delete mode 100644 webkit/glue/plugins/gtk_plugin_container.cc delete mode 100644 webkit/glue/plugins/gtk_plugin_container.h delete mode 100644 webkit/glue/plugins/gtk_plugin_container_manager.cc delete mode 100644 webkit/glue/plugins/gtk_plugin_container_manager.h delete mode 100644 webkit/glue/plugins/npapi_extension_thunk.cc delete mode 100644 webkit/glue/plugins/npapi_extension_thunk.h delete mode 100644 webkit/glue/plugins/pepper_audio.cc delete mode 100644 webkit/glue/plugins/pepper_audio.h delete mode 100644 webkit/glue/plugins/pepper_buffer.cc delete mode 100644 webkit/glue/plugins/pepper_buffer.h delete mode 100644 webkit/glue/plugins/pepper_char_set.cc delete mode 100644 webkit/glue/plugins/pepper_char_set.h delete mode 100644 webkit/glue/plugins/pepper_class.h delete mode 100644 webkit/glue/plugins/pepper_common.h delete mode 100644 webkit/glue/plugins/pepper_cursor_control.cc delete mode 100644 webkit/glue/plugins/pepper_cursor_control.h delete mode 100644 webkit/glue/plugins/pepper_dir_contents.h delete mode 100644 webkit/glue/plugins/pepper_directory_reader.cc delete mode 100644 webkit/glue/plugins/pepper_directory_reader.h delete mode 100644 webkit/glue/plugins/pepper_error_util.cc delete mode 100644 webkit/glue/plugins/pepper_error_util.h delete mode 100644 webkit/glue/plugins/pepper_event_conversion.cc delete mode 100644 webkit/glue/plugins/pepper_event_conversion.h delete mode 100644 webkit/glue/plugins/pepper_file_callbacks.cc delete mode 100644 webkit/glue/plugins/pepper_file_callbacks.h delete mode 100644 webkit/glue/plugins/pepper_file_chooser.cc delete mode 100644 webkit/glue/plugins/pepper_file_chooser.h delete mode 100644 webkit/glue/plugins/pepper_file_io.cc delete mode 100644 webkit/glue/plugins/pepper_file_io.h delete mode 100644 webkit/glue/plugins/pepper_file_ref.cc delete mode 100644 webkit/glue/plugins/pepper_file_ref.h delete mode 100644 webkit/glue/plugins/pepper_file_system.cc delete mode 100644 webkit/glue/plugins/pepper_file_system.h delete mode 100644 webkit/glue/plugins/pepper_font.cc delete mode 100644 webkit/glue/plugins/pepper_font.h delete mode 100644 webkit/glue/plugins/pepper_fullscreen_container.h delete mode 100644 webkit/glue/plugins/pepper_graphics_2d.cc delete mode 100644 webkit/glue/plugins/pepper_graphics_2d.h delete mode 100644 webkit/glue/plugins/pepper_graphics_3d.cc delete mode 100644 webkit/glue/plugins/pepper_graphics_3d.h delete mode 100644 webkit/glue/plugins/pepper_graphics_3d_gl.cc delete mode 100644 webkit/glue/plugins/pepper_image_data.cc delete mode 100644 webkit/glue/plugins/pepper_image_data.h delete mode 100644 webkit/glue/plugins/pepper_plugin_delegate.h delete mode 100644 webkit/glue/plugins/pepper_plugin_instance.cc delete mode 100644 webkit/glue/plugins/pepper_plugin_instance.h delete mode 100644 webkit/glue/plugins/pepper_plugin_module.cc delete mode 100644 webkit/glue/plugins/pepper_plugin_module.h delete mode 100644 webkit/glue/plugins/pepper_plugin_object.cc delete mode 100644 webkit/glue/plugins/pepper_plugin_object.h delete mode 100644 webkit/glue/plugins/pepper_private.cc delete mode 100644 webkit/glue/plugins/pepper_private.h delete mode 100644 webkit/glue/plugins/pepper_private2.cc delete mode 100644 webkit/glue/plugins/pepper_private2.h delete mode 100644 webkit/glue/plugins/pepper_private2_linux.cc delete mode 100644 webkit/glue/plugins/pepper_resource.cc delete mode 100644 webkit/glue/plugins/pepper_resource.h delete mode 100644 webkit/glue/plugins/pepper_resource_tracker.cc delete mode 100644 webkit/glue/plugins/pepper_resource_tracker.h delete mode 100644 webkit/glue/plugins/pepper_scrollbar.cc delete mode 100644 webkit/glue/plugins/pepper_scrollbar.h delete mode 100644 webkit/glue/plugins/pepper_string.cc delete mode 100644 webkit/glue/plugins/pepper_string.h delete mode 100644 webkit/glue/plugins/pepper_transport.cc delete mode 100644 webkit/glue/plugins/pepper_transport.h delete mode 100644 webkit/glue/plugins/pepper_url_loader.cc delete mode 100644 webkit/glue/plugins/pepper_url_loader.h delete mode 100644 webkit/glue/plugins/pepper_url_request_info.cc delete mode 100644 webkit/glue/plugins/pepper_url_request_info.h delete mode 100644 webkit/glue/plugins/pepper_url_response_info.cc delete mode 100644 webkit/glue/plugins/pepper_url_response_info.h delete mode 100644 webkit/glue/plugins/pepper_url_util.cc delete mode 100644 webkit/glue/plugins/pepper_url_util.h delete mode 100644 webkit/glue/plugins/pepper_var.cc delete mode 100644 webkit/glue/plugins/pepper_var.h delete mode 100644 webkit/glue/plugins/pepper_video_decoder.cc delete mode 100644 webkit/glue/plugins/pepper_video_decoder.h delete mode 100644 webkit/glue/plugins/pepper_webplugin_impl.cc delete mode 100644 webkit/glue/plugins/pepper_webplugin_impl.h delete mode 100644 webkit/glue/plugins/pepper_widget.cc delete mode 100644 webkit/glue/plugins/pepper_widget.h delete mode 100644 webkit/glue/plugins/plugin_constants_win.h delete mode 100644 webkit/glue/plugins/plugin_group.cc delete mode 100644 webkit/glue/plugins/plugin_group.h delete mode 100644 webkit/glue/plugins/plugin_group_unittest.cc delete mode 100644 webkit/glue/plugins/plugin_host.cc delete mode 100644 webkit/glue/plugins/plugin_host.h delete mode 100644 webkit/glue/plugins/plugin_instance.cc delete mode 100644 webkit/glue/plugins/plugin_instance.h delete mode 100644 webkit/glue/plugins/plugin_instance_mac.mm delete mode 100644 webkit/glue/plugins/plugin_lib.cc delete mode 100644 webkit/glue/plugins/plugin_lib.h delete mode 100644 webkit/glue/plugins/plugin_lib_mac.mm delete mode 100644 webkit/glue/plugins/plugin_lib_posix.cc delete mode 100644 webkit/glue/plugins/plugin_lib_unittest.cc delete mode 100644 webkit/glue/plugins/plugin_lib_win.cc delete mode 100644 webkit/glue/plugins/plugin_list.cc delete mode 100644 webkit/glue/plugins/plugin_list_mac.mm delete mode 100644 webkit/glue/plugins/plugin_list_posix.cc delete mode 100644 webkit/glue/plugins/plugin_list_win.cc delete mode 100644 webkit/glue/plugins/plugin_stream.cc delete mode 100644 webkit/glue/plugins/plugin_stream.h delete mode 100644 webkit/glue/plugins/plugin_stream_posix.cc delete mode 100644 webkit/glue/plugins/plugin_stream_url.cc delete mode 100644 webkit/glue/plugins/plugin_stream_url.h delete mode 100644 webkit/glue/plugins/plugin_stream_win.cc delete mode 100644 webkit/glue/plugins/plugin_string_stream.cc delete mode 100644 webkit/glue/plugins/plugin_string_stream.h delete mode 100644 webkit/glue/plugins/plugin_stubs.cc delete mode 100644 webkit/glue/plugins/plugin_switches.cc delete mode 100644 webkit/glue/plugins/plugin_switches.h delete mode 100644 webkit/glue/plugins/plugin_web_event_converter_mac.h delete mode 100644 webkit/glue/plugins/plugin_web_event_converter_mac.mm delete mode 100644 webkit/glue/plugins/ppb_private.h delete mode 100644 webkit/glue/plugins/ppb_private2.h delete mode 100644 webkit/glue/plugins/ppp_private.h delete mode 100644 webkit/glue/plugins/quickdraw_drawing_manager_mac.cc delete mode 100644 webkit/glue/plugins/quickdraw_drawing_manager_mac.h delete mode 100644 webkit/glue/plugins/test/Info.plist delete mode 100644 webkit/glue/plugins/test/npapi_constants.cc delete mode 100644 webkit/glue/plugins/test/npapi_constants.h delete mode 100644 webkit/glue/plugins/test/npapi_test.cc delete mode 100644 webkit/glue/plugins/test/npapi_test.def delete mode 100644 webkit/glue/plugins/test/npapi_test.rc delete mode 100644 webkit/glue/plugins/test/plugin_arguments_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_arguments_test.h delete mode 100644 webkit/glue/plugins/test/plugin_client.cc delete mode 100644 webkit/glue/plugins/test/plugin_client.h delete mode 100644 webkit/glue/plugins/test/plugin_create_instance_in_paint.cc delete mode 100644 webkit/glue/plugins/test/plugin_create_instance_in_paint.h delete mode 100644 webkit/glue/plugins/test/plugin_delete_plugin_in_stream_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_delete_plugin_in_stream_test.h delete mode 100644 webkit/glue/plugins/test/plugin_get_javascript_url2_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_get_javascript_url2_test.h delete mode 100644 webkit/glue/plugins/test/plugin_get_javascript_url_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_get_javascript_url_test.h delete mode 100644 webkit/glue/plugins/test/plugin_geturl_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_geturl_test.h delete mode 100644 webkit/glue/plugins/test/plugin_javascript_open_popup.cc delete mode 100644 webkit/glue/plugins/test/plugin_javascript_open_popup.h delete mode 100644 webkit/glue/plugins/test/plugin_new_fails_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_new_fails_test.h delete mode 100644 webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_npobject_lifetime_test.h delete mode 100644 webkit/glue/plugins/test/plugin_npobject_proxy_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_npobject_proxy_test.h delete mode 100644 webkit/glue/plugins/test/plugin_private_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_private_test.h delete mode 100644 webkit/glue/plugins/test/plugin_schedule_timer_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_schedule_timer_test.h delete mode 100644 webkit/glue/plugins/test/plugin_setup_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_setup_test.h delete mode 100644 webkit/glue/plugins/test/plugin_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_test.h delete mode 100644 webkit/glue/plugins/test/plugin_test_factory.cc delete mode 100644 webkit/glue/plugins/test/plugin_test_factory.h delete mode 100644 webkit/glue/plugins/test/plugin_thread_async_call_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_thread_async_call_test.h delete mode 100644 webkit/glue/plugins/test/plugin_window_size_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_window_size_test.h delete mode 100644 webkit/glue/plugins/test/plugin_windowed_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_windowed_test.h delete mode 100644 webkit/glue/plugins/test/plugin_windowless_test.cc delete mode 100644 webkit/glue/plugins/test/plugin_windowless_test.h delete mode 100644 webkit/glue/plugins/test/resource.h delete mode 100644 webkit/glue/plugins/webplugin.cc delete mode 100644 webkit/glue/plugins/webplugin.h delete mode 100644 webkit/glue/plugins/webplugin_2d_device_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_3d_device_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_accelerated_surface_mac.h delete mode 100644 webkit/glue/plugins/webplugin_audio_device_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_delegate_impl.cc delete mode 100644 webkit/glue/plugins/webplugin_delegate_impl.h delete mode 100644 webkit/glue/plugins/webplugin_delegate_impl_gtk.cc delete mode 100644 webkit/glue/plugins/webplugin_delegate_impl_mac.mm delete mode 100644 webkit/glue/plugins/webplugin_delegate_impl_win.cc delete mode 100644 webkit/glue/plugins/webplugin_file_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_impl.cc delete mode 100644 webkit/glue/plugins/webplugin_impl.h delete mode 100644 webkit/glue/plugins/webplugin_impl_unittest.cc delete mode 100644 webkit/glue/plugins/webplugin_page_delegate.h delete mode 100644 webkit/glue/plugins/webplugin_print_delegate.h delete mode 100644 webkit/glue/plugins/webplugininfo.cc delete mode 100644 webkit/glue/plugins/webplugininfo.h delete mode 100644 webkit/glue/plugins/webview_plugin.cc delete mode 100644 webkit/glue/plugins/webview_plugin.h (limited to 'webkit') diff --git a/webkit/glue/bookmarklet_unittest.cc b/webkit/glue/bookmarklet_unittest.cc index 5d8a364..d7fada5 100644 --- a/webkit/glue/bookmarklet_unittest.cc +++ b/webkit/glue/bookmarklet_unittest.cc @@ -26,8 +26,8 @@ TEST_F(BookmarkletTest, Redirect) { test_shell_->LoadURL( GURL("javascript:location.href='data:text/plain,SUCCESS'")); test_shell_->WaitTestFinished(); - std::wstring text = test_shell_->GetDocumentText(); - EXPECT_EQ(L"SUCCESS", text); + string16 text = test_shell_->GetDocumentText(); + EXPECT_EQ("SUCCESS", UTF16ToASCII(text)); } TEST_F(BookmarkletTest, RedirectVoided) { @@ -38,12 +38,12 @@ TEST_F(BookmarkletTest, RedirectVoided) { test_shell_->LoadURL( GURL("javascript:void(location.href='data:text/plain,SUCCESS')")); test_shell_->WaitTestFinished(); - std::wstring text = test_shell_->GetDocumentText(); - EXPECT_EQ(L"SUCCESS", text); + string16 text = test_shell_->GetDocumentText(); + EXPECT_EQ("SUCCESS", UTF16ToASCII(text)); } TEST_F(BookmarkletTest, NonEmptyResult) { - std::wstring text; + string16 text; // TODO(darin): This test fails in a JSC build. WebCore+JSC does not really // need to support this usage until WebCore supports javascript: URLs that @@ -54,13 +54,13 @@ TEST_F(BookmarkletTest, NonEmptyResult) { test_shell_->LoadURL(L"javascript:false"); MessageLoop::current()->RunAllPending(); text = test_shell_->GetDocumentText(); - EXPECT_EQ(L"false", text); + EXPECT_EQ("false", UTF16ToASCII(text)); #endif test_shell_->LoadURL(GURL("javascript:'hello world'")); MessageLoop::current()->RunAllPending(); text = test_shell_->GetDocumentText(); - EXPECT_EQ(L"hello world", text); + EXPECT_EQ("hello world", UTF16ToASCII(text)); } TEST_F(BookmarkletTest, DocumentWrite) { @@ -69,8 +69,8 @@ TEST_F(BookmarkletTest, DocumentWrite) { "document.write('hello world');" "document.close()")); MessageLoop::current()->RunAllPending(); - std::wstring text = test_shell_->GetDocumentText(); - EXPECT_EQ(L"hello world", text); + string16 text = test_shell_->GetDocumentText(); + EXPECT_EQ("hello world", UTF16ToASCII(text)); } } // namespace diff --git a/webkit/glue/context_menu.cc b/webkit/glue/context_menu.cc index 390d740..bdfe790 100644 --- a/webkit/glue/context_menu.cc +++ b/webkit/glue/context_menu.cc @@ -18,7 +18,7 @@ ContextMenuParams::ContextMenuParams(const WebKit::WebContextMenuData& data) page_url(data.pageURL), frame_url(data.frameURL), media_flags(data.mediaFlags), - selection_text(UTF16ToWideHack(data.selectedText)), + selection_text(data.selectedText), misspelled_word(data.misspelledWord), spellcheck_enabled(data.isSpellCheckingEnabled), is_editable(data.isEditable), diff --git a/webkit/glue/context_menu.h b/webkit/glue/context_menu.h index b681a38..c87de41 100644 --- a/webkit/glue/context_menu.h +++ b/webkit/glue/context_menu.h @@ -8,7 +8,7 @@ #include #include "base/basictypes.h" -#include "base/utf_string_conversions.h" +#include "base/string16.h" #include "googleurl/src/gurl.h" #include "webkit/glue/webmenuitem.h" @@ -57,7 +57,7 @@ struct ContextMenuParams { int media_flags; // This is the text of the selection that the context menu was invoked on. - std::wstring selection_text; + string16 selection_text; // The misspelled word under the cursor, if any. Used to generate the // |dictionary_suggestions| list. diff --git a/webkit/glue/cpp_bound_class.cc b/webkit/glue/cpp_bound_class.cc index d58fc4e..c5d15b6 100644 --- a/webkit/glue/cpp_bound_class.cc +++ b/webkit/glue/cpp_bound_class.cc @@ -319,7 +319,7 @@ CppVariant* CppBoundClass::GetAsCppVariant() { } void CppBoundClass::BindToJavascript(WebFrame* frame, - const std::wstring& classname) { + const std::string& classname) { #if WEBKIT_USING_JSC #error "This is not going to work anymore...but it's not clear what the solution is...or if it's still necessary." JSC::JSLock lock(false); @@ -328,7 +328,7 @@ void CppBoundClass::BindToJavascript(WebFrame* frame, // BindToWindowObject will take its own reference to the NPObject, and clean // up after itself. It will also (indirectly) register the object with V8, // so we must remember this so we can unregister it when we're destroyed. - frame->bindToWindowObject(WideToUTF16Hack(classname), + frame->bindToWindowObject(ASCIIToUTF16(classname), NPVARIANT_TO_OBJECT(*GetAsCppVariant())); bound_to_frame_ = true; } diff --git a/webkit/glue/cpp_bound_class.h b/webkit/glue/cpp_bound_class.h index a446386..06662ce 100644 --- a/webkit/glue/cpp_bound_class.h +++ b/webkit/glue/cpp_bound_class.h @@ -65,8 +65,7 @@ class CppBoundClass { // as window.. The owner of the CppBoundObject is responsible for // keeping the object around while the frame is alive, and for destroying it // afterwards. - void BindToJavascript( - WebKit::WebFrame* frame, const std::wstring& classname); + void BindToJavascript(WebKit::WebFrame* frame, const std::string& classname); // The type of callbacks. typedef Callback2::Type Callback; diff --git a/webkit/glue/cpp_bound_class_unittest.cc b/webkit/glue/cpp_bound_class_unittest.cc index f40b66b..54581ad 100644 --- a/webkit/glue/cpp_bound_class_unittest.cc +++ b/webkit/glue/cpp_bound_class_unittest.cc @@ -9,6 +9,7 @@ #include #include "base/message_loop.h" +#include "base/string_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebData.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" @@ -63,7 +64,7 @@ class ExampleTestShell : public TestShell { // When called by WebViewDelegate::WindowObjectCleared method, this binds a // CppExampleObject to window.example. virtual void BindJSObjectsToWindow(WebFrame* frame) { - example_bound_class_.BindToJavascript(frame, L"example"); + example_bound_class_.BindToJavascript(frame, "example"); // We use the layoutTestController binding for notifyDone. TestShell::BindJSObjectsToWindow(frame); } @@ -113,14 +114,15 @@ class CppBoundClassTest : public TestShellTest { // document text is exactly "SUCCESS". void CheckJavaScriptSuccess(const std::string& javascript) { ExecuteJavaScript(javascript); - EXPECT_EQ(L"SUCCESS", webkit_glue::DumpDocumentText(webframe_)); + EXPECT_EQ("SUCCESS", + UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_))); } // Executes the specified JavaScript and checks that the resulting document // text is empty. void CheckJavaScriptFailure(const std::string& javascript) { ExecuteJavaScript(javascript); - EXPECT_EQ(L"", webkit_glue::DumpDocumentText(webframe_)); + EXPECT_EQ("", UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_))); } // Constructs a JavaScript snippet that evaluates and compares the left and @@ -238,8 +240,7 @@ TEST_F(CppBoundClassTest, InvokeMethods) { "example.echoValue()", "null", // Too few arguments "example.echoType(false)", "true", - // Re-enable after merging r72243. - //"example.echoType(19)", "3.14159", + "example.echoType(19)", "3.14159", "example.echoType(9.876)", "3.14159", "example.echoType('test string')", "'Success!'", "example.echoType()", "null", // Too few arguments diff --git a/webkit/glue/cpp_variant.cc b/webkit/glue/cpp_variant.cc index 8545bc1..0d16cdd 100644 --- a/webkit/glue/cpp_variant.cc +++ b/webkit/glue/cpp_variant.cc @@ -211,10 +211,9 @@ bool CppVariant::ToBoolean() const { return value.boolValue; } -std::vector CppVariant::ToStringVector() const { - +std::vector CppVariant::ToStringVector() const { DCHECK(isObject()); - std::vector wstring_vector; + std::vector string_vector; NPObject* np_value = value.objectValue; NPIdentifier length_id = WebBindings::getStringIdentifier("length"); @@ -242,7 +241,7 @@ std::vector CppVariant::ToStringVector() const { std::string string( NPVARIANT_TO_STRING(index_value).UTF8Characters, NPVARIANT_TO_STRING(index_value).UTF8Length); - wstring_vector.push_back(UTF8ToWide(string)); + string_vector.push_back(string); } WebBindings::releaseVariantValue(&index_value); } @@ -250,7 +249,7 @@ std::vector CppVariant::ToStringVector() const { } } } - return wstring_vector; + return string_vector; } bool CppVariant::Invoke(const std::string& method, const CppVariant* args, diff --git a/webkit/glue/cpp_variant.h b/webkit/glue/cpp_variant.h index 71b3166..34f843a 100644 --- a/webkit/glue/cpp_variant.h +++ b/webkit/glue/cpp_variant.h @@ -96,7 +96,7 @@ class CppVariant : public NPVariant { bool ToBoolean() const; // Returns a vector of strings for the specified argument. This is useful // for converting a JavaScript array of strings into a vector of strings. - std::vector ToStringVector() const; + std::vector ToStringVector() const; // Invoke method of the given name on an object with the supplied arguments. // The first argument should be the object on which the method is to be diff --git a/webkit/glue/glue_serialize.cc b/webkit/glue/glue_serialize.cc index 835ae78..5b76784 100644 --- a/webkit/glue/glue_serialize.cc +++ b/webkit/glue/glue_serialize.cc @@ -343,7 +343,9 @@ static void WriteHistoryItem( // Creates a new HistoryItem tree based on the serialized string. // Assumes the data is in the format returned by WriteHistoryItem. static WebHistoryItem ReadHistoryItem( - const SerializeObject* obj, bool include_form_data) { + const SerializeObject* obj, + bool include_form_data, + bool include_scroll_offset) { // See note in WriteHistoryItem. on this. obj->version = ReadInteger(obj); @@ -368,9 +370,12 @@ static WebHistoryItem ReadHistoryItem( item.setTitle(ReadString(obj)); item.setAlternateTitle(ReadString(obj)); item.setLastVisitedTime(ReadReal(obj)); + int x = ReadInteger(obj); int y = ReadInteger(obj); - item.setScrollOffset(WebPoint(x, y)); + if (include_scroll_offset) + item.setScrollOffset(WebPoint(x, y)); + item.setIsTargetItem(ReadBoolean(obj)); item.setVisitCount(ReadInteger(obj)); item.setReferrer(ReadString(obj)); @@ -401,7 +406,9 @@ static WebHistoryItem ReadHistoryItem( // Subitems int num_children = ReadInteger(obj); for (int i = 0; i < num_children; ++i) - item.appendToChildren(ReadHistoryItem(obj, include_form_data)); + item.appendToChildren(ReadHistoryItem(obj, + include_form_data, + include_scroll_offset)); return item; } @@ -420,20 +427,22 @@ std::string HistoryItemToString(const WebHistoryItem& item) { // This assumes that the given serialized string has all the required key,value // pairs, and does minimal error checking. If |include_form_data| is true, // the form data from a post is restored, otherwise the form data is empty. +// If |include_scroll_offset| is true, the scroll offset is restored. static WebHistoryItem HistoryItemFromString( const std::string& serialized_item, - bool include_form_data) { + bool include_form_data, + bool include_scroll_offset) { if (serialized_item.empty()) return WebHistoryItem(); SerializeObject obj(serialized_item.data(), static_cast(serialized_item.length())); - return ReadHistoryItem(&obj, include_form_data); + return ReadHistoryItem(&obj, include_form_data, include_scroll_offset); } WebHistoryItem HistoryItemFromString( const std::string& serialized_item) { - return HistoryItemFromString(serialized_item, true); + return HistoryItemFromString(serialized_item, true, true); } // For testing purposes only. @@ -470,7 +479,22 @@ std::string CreateHistoryStateForURL(const GURL& url) { std::string RemoveFormDataFromHistoryState(const std::string& content_state) { // TODO(darin): We should avoid using the WebKit API here, so that we do not // need to have WebKit initialized before calling this method. - const WebHistoryItem& item = HistoryItemFromString(content_state, false); + const WebHistoryItem& item = + HistoryItemFromString(content_state, false, true); + if (item.isNull()) { + // Couldn't parse the string, return an empty string. + return std::string(); + } + + return HistoryItemToString(item); +} + +std::string RemoveScrollOffsetFromHistoryState( + const std::string& content_state) { + // TODO(darin): We should avoid using the WebKit API here, so that we do not + // need to have WebKit initialized before calling this method. + const WebHistoryItem& item = + HistoryItemFromString(content_state, true, false); if (item.isNull()) { // Couldn't parse the string, return an empty string. return std::string(); diff --git a/webkit/glue/media/audio_decoder.cc b/webkit/glue/media/audio_decoder.cc new file mode 100644 index 0000000..3fc05c9 --- /dev/null +++ b/webkit/glue/media/audio_decoder.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/media/audio_decoder.h" + +#include +#include "base/basictypes.h" +#include "base/string_util.h" +#include "base/time.h" +#include "media/filters/audio_file_reader.h" +#include "third_party/WebKit/WebKit/chromium/public/WebAudioBus.h" + +using media::AudioFileReader; +using media::InMemoryDataReader; +using std::vector; +using WebKit::WebAudioBus; + +namespace webkit_glue { + +// Decode in-memory audio file data. +bool DecodeAudioFileData( + WebKit::WebAudioBus* destination_bus, + const char* data, size_t data_size, double sample_rate) { + DCHECK(destination_bus); + if (!destination_bus) + return false; + + // Uses the FFmpeg library for audio file reading. + InMemoryDataReader data_reader(data, data_size); + AudioFileReader reader(&data_reader); + + if (!reader.Open()) + return false; + + size_t number_of_channels = reader.channels(); + double file_sample_rate = reader.sample_rate(); + double duration = reader.duration().InSecondsF(); + size_t number_of_frames = static_cast(reader.number_of_frames()); + + // TODO(crogers) : do sample-rate conversion with FFmpeg. + // For now, we're ignoring the requested 'sample_rate' and returning + // the WebAudioBus at the file's sample-rate. + // double destination_sample_rate = + // (sample_rate != 0.0) ? sample_rate : file_sample_rate; + double destination_sample_rate = file_sample_rate; + + DLOG(INFO) << "Decoding file data -" + << " data: " << data + << " data size: " << data_size + << " duration: " << duration + << " number of frames: " << number_of_frames + << " sample rate: " << file_sample_rate + << " number of channels: " << number_of_channels; + + // Change to destination sample-rate. + number_of_frames = static_cast(number_of_frames * + (destination_sample_rate / file_sample_rate)); + + // Allocate and configure the output audio channel data. + destination_bus->initialize(number_of_channels, + number_of_frames, + destination_sample_rate); + + // Wrap the channel pointers which will receive the decoded PCM audio. + vector audio_data; + audio_data.reserve(number_of_channels); + for (size_t i = 0; i < number_of_channels; ++i) { + audio_data.push_back(destination_bus->channelData(i)); + } + + // Decode the audio file data. + return reader.Read(audio_data, number_of_frames); +} + +} // namespace webkit_glue diff --git a/webkit/glue/media/audio_decoder.h b/webkit/glue/media/audio_decoder.h new file mode 100644 index 0000000..57cc90b --- /dev/null +++ b/webkit/glue/media/audio_decoder.h @@ -0,0 +1,20 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_MEDIA_AUDIO_DECODER_H_ +#define WEBKIT_GLUE_MEDIA_AUDIO_DECODER_H_ + +#include "base/basictypes.h" + +namespace WebKit { class WebAudioBus; } + +namespace webkit_glue { + +// Decode in-memory audio file data. +bool DecodeAudioFileData(WebKit::WebAudioBus* destination_bus, const char* data, + size_t data_size, double sample_rate); + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_MEDIA_AUDIO_DECODER_H_ diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index 29c86ac..b6efa16 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -2,46 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "base/process_util.h" -#include "base/stl_util-inl.h" -#include "base/string_util.h" +#include "webkit/glue/media/buffered_data_source.h" + #include "media/base/filter_host.h" -#include "media/base/media_format.h" -#include "net/base/load_flags.h" #include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "webkit/glue/media/buffered_data_source.h" #include "webkit/glue/webkit_glue.h" -#include "webkit/glue/webmediaplayer_impl.h" - -namespace { -const char kHttpScheme[] = "http"; -const char kHttpsScheme[] = "https"; -const char kDataScheme[] = "data"; -const int64 kPositionNotSpecified = -1; -const int kHttpOK = 200; -const int kHttpPartialContent = 206; +using WebKit::WebFrame; -// Define the number of bytes in a megabyte. -const size_t kMegabyte = 1024 * 1024; - -// Backward capacity of the buffer, by default 2MB. -const size_t kBackwardCapcity = 2 * kMegabyte; - -// Forward capacity of the buffer, by default 10MB. -const size_t kForwardCapacity = 10 * kMegabyte; - -// The threshold of bytes that we should wait until the data arrives in the -// future instead of restarting a new connection. This number is defined in the -// number of bytes, we should determine this value from typical connection speed -// and amount of time for a suitable wait. Now I just make a guess for this -// number to be 2MB. -// TODO(hclam): determine a better value for this. -const int kForwardWaitThreshold = 2 * kMegabyte; +namespace { // Defines how long we should wait for more data before we declare a connection // timeout and start a new request. @@ -58,479 +27,18 @@ const int kReadTrials = 3; // of FFmpeg. const int kInitialReadBufferSize = 32768; -// Returns true if |url| operates on HTTP protocol. -bool IsHttpProtocol(const GURL& url) { - return url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme); -} - -bool IsDataProtocol(const GURL& url) { - return url.SchemeIs(kDataScheme); -} - -} // namespace +} // namespace namespace webkit_glue { -///////////////////////////////////////////////////////////////////////////// -// BufferedResourceLoader -BufferedResourceLoader::BufferedResourceLoader( - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory, - const GURL& url, - int64 first_byte_position, - int64 last_byte_position) - : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), - deferred_(false), - defer_allowed_(true), - completed_(false), - range_requested_(false), - partial_response_(false), - bridge_factory_(bridge_factory), - url_(url), - first_byte_position_(first_byte_position), - last_byte_position_(last_byte_position), - start_callback_(NULL), - bridge_(NULL), - offset_(0), - content_length_(kPositionNotSpecified), - instance_size_(kPositionNotSpecified), - read_callback_(NULL), - read_position_(0), - read_size_(0), - read_buffer_(NULL), - first_offset_(0), - last_offset_(0) { -} - -BufferedResourceLoader::~BufferedResourceLoader() { -} - -void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, - NetworkEventCallback* event_callback) { - // Make sure we have not started. - DCHECK(!bridge_.get()); - DCHECK(!start_callback_.get()); - DCHECK(!event_callback_.get()); - DCHECK(start_callback); - DCHECK(event_callback); - - start_callback_.reset(start_callback); - event_callback_.reset(event_callback); - - if (first_byte_position_ != kPositionNotSpecified) { - range_requested_ = true; - // TODO(hclam): server may not support range request so |offset_| may not - // equal to |first_byte_position_|. - offset_ = first_byte_position_; - } - - // Creates the bridge on render thread since we can only access - // ResourceDispatcher on this thread. - bridge_.reset( - bridge_factory_->CreateBridge( - url_, - net::LOAD_NORMAL, - first_byte_position_, - last_byte_position_)); - - // Increment the reference count right before we start the request. This - // reference will be release when this request has ended. - AddRef(); - - // And start the resource loading. - bridge_->Start(this); -} - -void BufferedResourceLoader::Stop() { - // Reset callbacks. - start_callback_.reset(); - event_callback_.reset(); - read_callback_.reset(); - - // Use the internal buffer to signal that we have been stopped. - // TODO(hclam): Not so pretty to do this. - if (!buffer_.get()) - return; - - // Destroy internal buffer. - buffer_.reset(); - - if (bridge_.get()) { - // Cancel the request. This method call will cancel the request - // asynchronously. We may still get data or messages until we receive - // a response completed message. - if (deferred_) - bridge_->SetDefersLoading(false); - deferred_ = false; - bridge_->Cancel(); - } -} - -void BufferedResourceLoader::Read(int64 position, - int read_size, - uint8* buffer, - net::CompletionCallback* read_callback) { - DCHECK(!read_callback_.get()); - DCHECK(buffer_.get()); - DCHECK(read_callback); - DCHECK(buffer); - - // Save the parameter of reading. - read_callback_.reset(read_callback); - read_position_ = position; - read_size_ = read_size; - read_buffer_ = buffer; - // If read position is beyond the instance size, we cannot read there. - if (instance_size_ != kPositionNotSpecified && - instance_size_ <= read_position_) { - DoneRead(0); - return; - } - - // Make sure |offset_| and |read_position_| does not differ by a large - // amount. - if (read_position_ > offset_ + kint32max || - read_position_ < offset_ + kint32min) { - DoneRead(net::ERR_CACHE_MISS); - return; - } - - // Prepare the parameters. - first_offset_ = static_cast(read_position_ - offset_); - last_offset_ = first_offset_ + read_size_; - - // If we can serve the request now, do the actual read. - if (CanFulfillRead()) { - ReadInternal(); - DisableDeferIfNeeded(); - return; - } - - // If we expected the read request to be fulfilled later, returns - // immediately and let more data to flow in. - if (WillFulfillRead()) - return; - - // Make a callback to report failure. - DoneRead(net::ERR_CACHE_MISS); -} - -int64 BufferedResourceLoader::GetBufferedFirstBytePosition() { - if (buffer_.get()) - return offset_ - static_cast(buffer_->backward_bytes()); - return kPositionNotSpecified; -} - -int64 BufferedResourceLoader::GetBufferedLastBytePosition() { - if (buffer_.get()) - return offset_ + static_cast(buffer_->forward_bytes()) - 1; - return kPositionNotSpecified; -} - -void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { - defer_allowed_ = is_allowed; - DisableDeferIfNeeded(); -} - -///////////////////////////////////////////////////////////////////////////// -// BufferedResourceLoader, -// webkit_glue::ResourceLoaderBridge::Peer implementations -bool BufferedResourceLoader::OnReceivedRedirect( - const GURL& new_url, - const webkit_glue::ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies) { - DCHECK(bridge_.get()); - - // Save the new URL. - url_ = new_url; - // TODO(wtc): should we return a new first party for cookies URL? - *has_new_first_party_for_cookies = false; - - // The load may have been stopped and |start_callback| is destroyed. - // In this case we shouldn't do anything. - if (!start_callback_.get()) - return true; - - if (!IsProtocolSupportedForMedia(new_url)) { - DoneStart(net::ERR_ADDRESS_INVALID); - Stop(); - return false; - } - return true; -} - -void BufferedResourceLoader::OnReceivedResponse( - const webkit_glue::ResourceResponseInfo& info, - bool content_filtered) { - DCHECK(bridge_.get()); - - // The loader may have been stopped and |start_callback| is destroyed. - // In this case we shouldn't do anything. - if (!start_callback_.get()) - return; - - // We make a strong assumption that when we reach here we have either - // received a response from HTTP/HTTPS protocol or the request was - // successful (in particular range request). So we only verify the partial - // response for HTTP and HTTPS protocol. - if (IsHttpProtocol(url_)) { - int error = net::OK; - if (!info.headers) { - // We expect to receive headers because this is a HTTP or HTTPS protocol, - // if not report failure. - error = net::ERR_INVALID_RESPONSE; - } else { - if (info.headers->response_code() == kHttpPartialContent) - partial_response_ = true; - - if (range_requested_ && partial_response_) { - // If we have verified the partial response and it is correct, we will - // return net::OK. - if (!VerifyPartialResponse(info)) - error = net::ERR_INVALID_RESPONSE; - } else if (info.headers->response_code() != kHttpOK) { - // We didn't request a range but server didn't reply with "200 OK". - error = net::ERR_FAILED; - } - } - - if (error != net::OK) { - DoneStart(error); - Stop(); - return; - } - } else { - // For any protocol other than HTTP and HTTPS, assume range request is - // always fulfilled. - partial_response_ = range_requested_; - } - - // |info.content_length| can be -1, in that case |content_length_| is - // not specified and this is a streaming response. - content_length_ = info.content_length; - - // If we have not requested a range, then the size of the instance is equal - // to the content length. - if (!partial_response_) - instance_size_ = content_length_; - - // Calls with a successful response. - DoneStart(net::OK); -} - -void BufferedResourceLoader::OnReceivedData(const char* data, int len) { - DCHECK(bridge_.get()); - - // If this loader has been stopped, |buffer_| would be destroyed. - // In this case we shouldn't do anything. - if (!buffer_.get()) - return; - - // Writes more data to |buffer_|. - buffer_->Append(reinterpret_cast(data), len); - - // If there is an active read request, try to fulfill the request. - if (HasPendingRead() && CanFulfillRead()) { - ReadInternal(); - } else if (!defer_allowed_) { - // If we're not allowed to defer, slide the buffer window forward instead - // of deferring. - if (buffer_->forward_bytes() > buffer_->forward_capacity()) { - size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); - bool success = buffer_->Seek(excess); - DCHECK(success); - offset_ += first_offset_ + excess; - } - } - - // At last see if the buffer is full and we need to defer the downloading. - EnableDeferIfNeeded(); - - // Notify that we have received some data. - NotifyNetworkEvent(); -} - -void BufferedResourceLoader::OnCompletedRequest( - const URLRequestStatus& status, - const std::string& security_info, - const base::Time& completion_time) { - DCHECK(bridge_.get()); - - // Saves the information that the request has completed. - completed_ = true; - - // If there is a start callback, calls it. - if (start_callback_.get()) { - DoneStart(status.os_error()); - } - - // If there is a pending read but the request has ended, returns with what - // we have. - if (HasPendingRead()) { - // Make sure we have a valid buffer before we satisfy a read request. - DCHECK(buffer_.get()); - - if (status.is_success()) { - // Try to fulfill with what is in the buffer. - if (CanFulfillRead()) - ReadInternal(); - else - DoneRead(net::ERR_CACHE_MISS); - } else { - // If the request has failed, then fail the read. - DoneRead(net::ERR_FAILED); - } - } - - // There must not be any outstanding read request. - DCHECK(!HasPendingRead()); - - // Notify that network response is completed. - NotifyNetworkEvent(); - - // We incremented the reference count when the loader was started. We balance - // that reference here so that we get destroyed. This is also the only safe - // place to destroy the ResourceLoaderBridge. - bridge_.reset(); - Release(); -} - -///////////////////////////////////////////////////////////////////////////// -// BufferedResourceLoader, private -void BufferedResourceLoader::EnableDeferIfNeeded() { - if (!defer_allowed_) - return; - - if (!deferred_ && - buffer_->forward_bytes() >= buffer_->forward_capacity()) { - deferred_ = true; - - if (bridge_.get()) - bridge_->SetDefersLoading(true); - - NotifyNetworkEvent(); - } -} - -void BufferedResourceLoader::DisableDeferIfNeeded() { - if (deferred_ && - (!defer_allowed_ || - buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { - deferred_ = false; - - if (bridge_.get()) - bridge_->SetDefersLoading(false); - - NotifyNetworkEvent(); - } -} - -bool BufferedResourceLoader::CanFulfillRead() { - // If we are reading too far in the backward direction. - if (first_offset_ < 0 && - first_offset_ + static_cast(buffer_->backward_bytes()) < 0) - return false; - - // If the start offset is too far ahead. - if (first_offset_ >= static_cast(buffer_->forward_bytes())) - return false; - - // At the point, we verified that first byte requested is within the buffer. - // If the request has completed, then just returns with what we have now. - if (completed_) - return true; - - // If the resource request is still active, make sure the whole requested - // range is covered. - if (last_offset_ > static_cast(buffer_->forward_bytes())) - return false; - - return true; -} - -bool BufferedResourceLoader::WillFulfillRead() { - // Reading too far in the backward direction. - if (first_offset_ < 0 && - first_offset_ + static_cast(buffer_->backward_bytes()) < 0) - return false; - - // Try to read too far ahead. - if (last_offset_ > kForwardWaitThreshold) - return false; - - // The resource request has completed, there's no way we can fulfill the - // read request. - if (completed_) - return false; - - return true; -} - -void BufferedResourceLoader::ReadInternal() { - // Seek to the first byte requested. - bool ret = buffer_->Seek(first_offset_); - DCHECK(ret); - - // Then do the read. - int read = static_cast(buffer_->Read(read_buffer_, read_size_)); - offset_ += first_offset_ + read; - - // And report with what we have read. - DoneRead(read); -} - -bool BufferedResourceLoader::VerifyPartialResponse( - const ResourceResponseInfo& info) { - int64 first_byte_position, last_byte_position, instance_size; - if (!info.headers->GetContentRange(&first_byte_position, - &last_byte_position, - &instance_size)) { - return false; - } - - if (instance_size != kPositionNotSpecified) - instance_size_ = instance_size; - - if (first_byte_position_ != -1 && - first_byte_position_ != first_byte_position) { - return false; - } - - // TODO(hclam): I should also check |last_byte_position|, but since - // we will never make such a request that it is ok to leave it unimplemented. - return true; -} - -void BufferedResourceLoader::DoneRead(int error) { - read_callback_->RunWithParams(Tuple1(error)); - read_callback_.reset(); - read_position_ = 0; - read_size_ = 0; - read_buffer_ = NULL; - first_offset_ = 0; - last_offset_ = 0; -} - -void BufferedResourceLoader::DoneStart(int error) { - start_callback_->RunWithParams(Tuple1(error)); - start_callback_.reset(); -} - -void BufferedResourceLoader::NotifyNetworkEvent() { - if (event_callback_.get()) - event_callback_->Run(); -} - -///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource BufferedDataSource::BufferedDataSource( MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) + WebFrame* frame) : total_bytes_(kPositionNotSpecified), loaded_(false), streaming_(false), + frame_(frame), single_origin_(true), - bridge_factory_(bridge_factory), loader_(NULL), network_activity_(false), initialize_callback_(NULL), @@ -558,7 +66,7 @@ BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( int64 first_byte_position, int64 last_byte_position) { DCHECK(MessageLoop::current() == render_loop_); - return new BufferedResourceLoader(bridge_factory_.get(), url_, + return new BufferedResourceLoader(url_, first_byte_position, last_byte_position); } @@ -571,7 +79,7 @@ base::TimeDelta BufferedDataSource::GetTimeoutMilliseconds() { } ///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, media::MediaFilter implementation +// media::Filter implementation. void BufferedDataSource::Initialize(const std::string& url, media::FilterCallback* callback) { // Saves the url. @@ -602,7 +110,7 @@ bool BufferedDataSource::IsUrlSupported(const std::string& url) { GURL gurl(url); // This data source doesn't support data:// protocol so reject it. - return IsProtocolSupportedForMedia(gurl) && !IsDataProtocol(gurl); + return IsProtocolSupportedForMedia(gurl) && !gurl.SchemeIs(kDataScheme); } void BufferedDataSource::Stop(media::FilterCallback* callback) { @@ -626,7 +134,7 @@ void BufferedDataSource::SetPlaybackRate(float playback_rate) { } ///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, media::DataSource implementation +// media::DataSource implementation. void BufferedDataSource::Read(int64 position, size_t size, uint8* data, media::DataSource::ReadCallback* read_callback) { render_loop_->PostTask(FROM_HERE, @@ -658,20 +166,21 @@ void BufferedDataSource::Abort() { // If we are told to abort, immediately return from any pending read // with an error. if (read_callback_.get()) { - { AutoLock auto_lock(lock_); DoneRead_Locked(net::ERR_FAILED); - } - CleanupTask(); } + + CleanupTask(); + frame_ = NULL; } ///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, render thread tasks +// Render thread tasks. void BufferedDataSource::InitializeTask() { DCHECK(MessageLoop::current() == render_loop_); DCHECK(!loader_.get()); - DCHECK(!stopped_on_render_loop_); + if (stopped_on_render_loop_) + return; // Kick starts the watch dog task that will handle connection timeout. // We run the watch dog 2 times faster the actual timeout so as to catch @@ -681,24 +190,24 @@ void BufferedDataSource::InitializeTask() { this, &BufferedDataSource::WatchDogTask); - if (IsHttpProtocol(url_)) { - // Fetch only first 1024 bytes as this usually covers the header portion - // of a media file that gives enough information about the codecs, etc. - // This also serve as a probe to determine server capability to serve - // range request. - // TODO(hclam): Do some experiments for the best approach. - loader_ = CreateResourceLoader(0, 1024); + if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { + // Do an unbounded range request starting at the beginning. If the server + // responds with 200 instead of 206 we'll fall back into a streaming mode. + loader_ = CreateResourceLoader(0, kPositionNotSpecified); loader_->Start( NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + NewCallback(this, &BufferedDataSource::NetworkEventCallback), + frame_); } else { // For all other protocols, assume they support range request. We fetch // the full range of the resource to obtain the instance size because // we won't be served HTTP headers. - loader_ = CreateResourceLoader(-1, -1); + loader_ = CreateResourceLoader(kPositionNotSpecified, + kPositionNotSpecified); loader_->Start( NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + NewCallback(this, &BufferedDataSource::NetworkEventCallback), + frame_); } } @@ -706,11 +215,6 @@ void BufferedDataSource::ReadTask( int64 position, int read_size, uint8* buffer, media::DataSource::ReadCallback* read_callback) { DCHECK(MessageLoop::current() == render_loop_); - - // If CleanupTask() was executed we should return immediately. We check this - // variable to prevent doing any actual work after clean up was done. We do - // not check |stop_signal_received_| because anything use of it has to be - // within |lock_| which is not desirable. if (stopped_on_render_loop_) return; @@ -731,8 +235,6 @@ void BufferedDataSource::ReadTask( void BufferedDataSource::CleanupTask() { DCHECK(MessageLoop::current() == render_loop_); - - // If we have already stopped, do nothing. if (stopped_on_render_loop_) return; @@ -757,13 +259,6 @@ void BufferedDataSource::CleanupTask() { void BufferedDataSource::RestartLoadingTask() { DCHECK(MessageLoop::current() == render_loop_); - - // This variable is set in CleanupTask(). We check this and do an early - // return. The sequence of actions which enable this conditions is: - // 1. Stop() is called from the pipeline. - // 2. ReadCallback() is called from the resource loader. - // 3. CleanupTask() is executed. - // 4. RestartLoadingTask() is executed. if (stopped_on_render_loop_) return; @@ -771,16 +266,18 @@ void BufferedDataSource::RestartLoadingTask() { if (!read_callback_.get()) return; - loader_ = CreateResourceLoader(read_position_, -1); + loader_ = CreateResourceLoader(read_position_, kPositionNotSpecified); loader_->SetAllowDefer(!media_is_paused_); loader_->Start( NewCallback(this, &BufferedDataSource::PartialReadStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + NewCallback(this, &BufferedDataSource::NetworkEventCallback), + frame_); } void BufferedDataSource::WatchDogTask() { DCHECK(MessageLoop::current() == render_loop_); - DCHECK(!stopped_on_render_loop_); + if (stopped_on_render_loop_) + return; // We only care if there is an active read request. if (!read_callback_.get()) @@ -802,11 +299,12 @@ void BufferedDataSource::WatchDogTask() { // Stops the current loader and creates a new resource loader and // retry the request. loader_->Stop(); - loader_ = CreateResourceLoader(read_position_, -1); + loader_ = CreateResourceLoader(read_position_, kPositionNotSpecified); loader_->SetAllowDefer(!media_is_paused_); loader_->Start( NewCallback(this, &BufferedDataSource::PartialReadStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + NewCallback(this, &BufferedDataSource::NetworkEventCallback), + frame_); } void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { @@ -829,7 +327,7 @@ void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { // prior to make this method call. void BufferedDataSource::ReadInternal() { DCHECK(MessageLoop::current() == render_loop_); - DCHECK(loader_.get()); + DCHECK(loader_); // First we prepare the intermediate read buffer for BufferedResourceLoader // to write to. @@ -872,9 +370,7 @@ void BufferedDataSource::DoneInitialization_Locked() { } ///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, callback methods. -// These methods are called on the render thread for the events reported by -// BufferedResourceLoader. +// BufferedResourceLoader callback methods. void BufferedDataSource::HttpInitialStartCallback(int error) { DCHECK(MessageLoop::current() == render_loop_); DCHECK(loader_.get()); @@ -901,10 +397,12 @@ void BufferedDataSource::HttpInitialStartCallback(int error) { // Assuming that the Range header was causing the problem. Retry without // the Range header. using_range_request_ = false; - loader_ = CreateResourceLoader(-1, -1); + loader_ = CreateResourceLoader(kPositionNotSpecified, + kPositionNotSpecified); loader_->Start( NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), - NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + NewCallback(this, &BufferedDataSource::NetworkEventCallback), + frame_); return; } @@ -1058,10 +556,10 @@ void BufferedDataSource::NetworkEventCallback() { return; bool network_activity = loader_->network_activity(); - int64 buffered_last_byte_position = loader_->GetBufferedLastBytePosition(); + int64 buffered_position = loader_->GetBufferedPosition(); // If we get an unspecified value, return immediately. - if (buffered_last_byte_position == kPositionNotSpecified) + if (buffered_position == kPositionNotSpecified) return; // We need to prevent calling to filter host and running the callback if @@ -1080,7 +578,7 @@ void BufferedDataSource::NetworkEventCallback() { network_activity_ = network_activity; host()->SetNetworkActivity(network_activity); } - host()->SetBufferedBytes(buffered_last_byte_position + 1); + host()->SetBufferedBytes(buffered_position + 1); } } // namespace webkit_glue diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h index 2af9e84..1c4e3fa 100644 --- a/webkit/glue/media/buffered_data_source.h +++ b/webkit/glue/media/buffered_data_source.h @@ -10,220 +10,18 @@ #include "base/callback.h" #include "base/lock.h" #include "base/scoped_ptr.h" -#include "base/timer.h" -#include "base/condition_variable.h" -#include "googleurl/src/gurl.h" -#include "media/base/filters.h" -#include "media/base/media_format.h" -#include "media/base/pipeline.h" -#include "media/base/seekable_buffer.h" -#include "net/base/completion_callback.h" -#include "net/base/file_stream.h" -#include "webkit/glue/media/media_resource_loader_bridge_factory.h" -#include "webkit/glue/media/web_data_source.h" -#include "webkit/glue/webmediaplayer_impl.h" +#include "webkit/glue/media/buffered_resource_loader.h" namespace webkit_glue { -///////////////////////////////////////////////////////////////////////////// -// BufferedResourceLoader -// This class works inside demuxer thread and render thread. It contains a -// resource loader bridge and does the actual resource loading. This object -// does buffering internally, it defers the resource loading if buffer is -// full and un-defers the resource loading if it is under buffered. -class BufferedResourceLoader : - public base::RefCountedThreadSafe, - public webkit_glue::ResourceLoaderBridge::Peer { - public: - typedef Callback0::Type NetworkEventCallback; - - // |bridge_factory| - Factory to create a ResourceLoaderBridge. - // |url| - URL for the resource to be loaded. - // |first_byte_position| - First byte to start loading from, -1 for not - // specified. - // |last_byte_position| - Last byte to be loaded, -1 for not specified. - BufferedResourceLoader( - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory, - const GURL& url, - int64 first_byte_position, - int64 last_byte_position); - - // Start the resource loading with the specified URL and range. - // This method operates in asynchronous mode. Once there's a response from the - // server, success or fail |callback| is called with the result. - // |callback| is called with the following values: - // - net::OK - // The request has started successfully. - // - net::ERR_FAILED - // The request has failed because of an error with the network. - // - net::ERR_INVALID_RESPONSE - // An invalid response is received from the server. - // - (Anything else) - // An error code that indicates the request has failed. - // |event_callback| is called when the response is completed, data is - // received, the request is suspended or resumed. - virtual void Start(net::CompletionCallback* callback, - NetworkEventCallback* event_callback); - - // Stop this loader, cancels and request and release internal buffer. - virtual void Stop(); - - // Reads the specified |read_size| from |position| into |buffer| and when - // the operation is done invoke |callback| with number of bytes read or an - // error code. - // |callback| is called with the following values: - // - (Anything greater than or equal 0) - // Read was successful with the indicated number of bytes read. - // - net::ERR_FAILED - // The read has failed because of an error with the network. - // - net::ERR_CACHE_MISS - // The read was made too far away from the current buffered position. - virtual void Read(int64 position, int read_size, - uint8* buffer, net::CompletionCallback* callback); - - // Returns the position of the first byte buffered. Returns -1 if such value - // is not available. - virtual int64 GetBufferedFirstBytePosition(); - - // Returns the position of the last byte buffered. Returns -1 if such value - // is not available. - virtual int64 GetBufferedLastBytePosition(); - - // Sets whether deferring data is allowed or disallowed. - virtual void SetAllowDefer(bool is_allowed); - - // Gets the content length in bytes of the instance after this loader has been - // started. If this value is -1, then content length is unknown. - virtual int64 content_length() { return content_length_; } - - // Gets the original size of the file requested. If this value is -1, then - // the size is unknown. - virtual int64 instance_size() { return instance_size_; } - - // Returns true if the response for this loader is a partial response. - // It means a 206 response in HTTP/HTTPS protocol. - virtual bool partial_response() { return partial_response_; } - - // Returns true if network is currently active. - virtual bool network_activity() { return !completed_ && !deferred_; } - - // Returns resulting URL. - virtual const GURL& url() { return url_; } - - ///////////////////////////////////////////////////////////////////////////// - // webkit_glue::ResourceLoaderBridge::Peer implementations. - virtual void OnUploadProgress(uint64 position, uint64 size) {} - virtual bool OnReceivedRedirect( - const GURL& new_url, - const webkit_glue::ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies); - virtual void OnReceivedResponse( - const webkit_glue::ResourceResponseInfo& info, - bool content_filtered); - virtual void OnDownloadedData(int len) {} - virtual void OnReceivedData(const char* data, int len); - virtual void OnCompletedRequest( - const URLRequestStatus& status, - const std::string& security_info, - const base::Time& completion_time); - - protected: - friend class base::RefCountedThreadSafe; - - virtual ~BufferedResourceLoader(); - - private: - friend class BufferedResourceLoaderTest; - - // Defer the resource loading if the buffer is full. - void EnableDeferIfNeeded(); - - // Disable defer loading if we are under-buffered. - void DisableDeferIfNeeded(); - - // Returns true if the current read request can be fulfilled by what is in - // the buffer. - bool CanFulfillRead(); - - // Returns true if the current read request will be fulfilled in the future. - bool WillFulfillRead(); - - // Method that does the actual read and calls the |read_callbac_|, assuming - // the request range is in |buffer_|. - void ReadInternal(); - - // If we have made a range request, verify the response from the server. - bool VerifyPartialResponse(const ResourceResponseInfo& info); - - // Done with read. Invokes the read callback and reset parameters for the - // read request. - void DoneRead(int error); - - // Done with start. Invokes the start callback and reset it. - void DoneStart(int error); - - // Calls |event_callback_| in terms of a network event. - void NotifyNetworkEvent(); - - bool HasPendingRead() { return read_callback_.get() != NULL; } - - // A sliding window of buffer. - scoped_ptr buffer_; - - // True if resource loading was deferred. - bool deferred_; - - // True if resource loader is allowed to defer, false otherwise. - bool defer_allowed_; - - // True if resource loading has completed. - bool completed_; - - // True if a range request was made. - bool range_requested_; - - // True if response data received is a partial range. - bool partial_response_; - - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory_; - GURL url_; - int64 first_byte_position_; - int64 last_byte_position_; - - // Callback method that listens to network events. - scoped_ptr event_callback_; - - // Members used during request start. - scoped_ptr start_callback_; - scoped_ptr bridge_; - int64 offset_; - int64 content_length_; - int64 instance_size_; - - // Members used during a read operation. They should be reset after each - // read has completed or failed. - scoped_ptr read_callback_; - int64 read_position_; - int read_size_; - uint8* read_buffer_; - - // Offsets of the requested first byte and last byte in |buffer_|. They are - // written by VerifyRead(). - int first_offset_; - int last_offset_; - - DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader); -}; class BufferedDataSource : public WebDataSource { public: - BufferedDataSource( - MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); + BufferedDataSource(MessageLoop* render_loop, + WebKit::WebFrame* frame); virtual ~BufferedDataSource(); - // media::MediaFilter implementation. + // media::Filter implementation. virtual void Initialize(const std::string& url, media::FilterCallback* callback); virtual bool IsUrlSupported(const std::string& url); @@ -247,7 +45,6 @@ class BufferedDataSource : public WebDataSource { virtual void Abort(); protected: - // A factory method to create a BufferedResourceLoader based on the read // parameters. We can override this file to object a mock // BufferedResourceLoader for testing. @@ -338,12 +135,12 @@ class BufferedDataSource : public WebDataSource { // i.e. range request is not supported. bool streaming_; + // A webframe for loading. + WebKit::WebFrame* frame_; + // True if the media resource has a single origin. bool single_origin_; - // A factory object to produce ResourceLoaderBridge. - scoped_ptr bridge_factory_; - // A resource loader for the media resource. scoped_refptr loader_; @@ -385,7 +182,7 @@ class BufferedDataSource : public WebDataSource { bool stop_signal_received_; // This variable is set by CleanupTask() that indicates this object is stopped - // on the render thread. + // on the render thread and work should no longer progress. bool stopped_on_render_loop_; // This variable is true when we are in a paused state and false when we diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc index 81103b2..dcb11ec 100644 --- a/webkit/glue/media/buffered_data_source_unittest.cc +++ b/webkit/glue/media/buffered_data_source_unittest.cc @@ -4,22 +4,18 @@ #include -#include "base/callback.h" -#include "base/format_macros.h" -#include "base/message_loop.h" -#include "base/string_util.h" -#include "base/stringprintf.h" -#include "media/base/filters.h" +#include "base/test/test_timeouts.h" #include "media/base/mock_filter_host.h" #include "media/base/mock_filters.h" #include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/glue/media/buffered_data_source.h" -#include "webkit/glue/media/mock_media_resource_loader_bridge_factory.h" -#include "webkit/glue/mock_resource_loader_bridge.h" +#include "webkit/mocks/mock_webframe.h" using ::testing::_; using ::testing::Assign; +using ::testing::AtLeast; using ::testing::DeleteArg; using ::testing::DoAll; using ::testing::InSequence; @@ -49,476 +45,36 @@ enum NetworkState { namespace webkit_glue { -// Submit a request completed event to the resource loader due to request -// being canceled. Pretending the event is from external. -ACTION_P(RequestCanceled, loader) { - URLRequestStatus status; - status.set_status(URLRequestStatus::CANCELED); - status.set_os_error(net::ERR_ABORTED); - loader->OnCompletedRequest(status, "", base::Time()); -} - -class BufferedResourceLoaderTest : public testing::Test { +// A mock BufferedDataSource to inject mock BufferedResourceLoader through +// CreateResourceLoader() method. +class MockBufferedDataSource : public BufferedDataSource { public: - BufferedResourceLoaderTest() { - bridge_.reset(new StrictMock()); - - for (int i = 0; i < kDataSize; ++i) - data_[i] = i; - } - - ~BufferedResourceLoaderTest() { - if (bridge_.get()) - EXPECT_CALL(*bridge_, OnDestroy()); - EXPECT_CALL(bridge_factory_, OnDestroy()); - } - - void Initialize(const char* url, int first_position, int last_position) { - gurl_ = GURL(url); - first_position_ = first_position; - last_position_ = last_position; - - loader_ = new BufferedResourceLoader(&bridge_factory_, gurl_, - first_position_, last_position_); - } - - void SetLoaderBuffer(size_t forward_capacity, size_t backward_capacity) { - loader_->buffer_.reset( - new media::SeekableBuffer(backward_capacity, forward_capacity)); - } - - void Start() { - InSequence s; - EXPECT_CALL(bridge_factory_, - CreateBridge(gurl_, _, first_position_, last_position_)) - .WillOnce(Return(bridge_.get())); - EXPECT_CALL(*bridge_, Start(loader_.get())); - loader_->Start( - NewCallback(this, &BufferedResourceLoaderTest::StartCallback), - NewCallback(this, &BufferedResourceLoaderTest::NetworkCallback)); - } - - void FullResponse(int64 instance_size) { - EXPECT_CALL(*this, StartCallback(net::OK)); - ResourceResponseInfo info; - std::string header = base::StringPrintf("HTTP/1.1 200 OK\n" - "Content-Length: %" PRId64, - instance_size); - replace(header.begin(), header.end(), '\n', '\0'); - info.headers = new net::HttpResponseHeaders(header); - info.content_length = instance_size; - loader_->OnReceivedResponse(info, false); - EXPECT_EQ(instance_size, loader_->content_length()); - EXPECT_EQ(instance_size, loader_->instance_size()); - EXPECT_FALSE(loader_->partial_response()); - } - - void PartialResponse(int64 first_position, int64 last_position, - int64 instance_size) { - EXPECT_CALL(*this, StartCallback(net::OK)); - int64 content_length = last_position - first_position + 1; - ResourceResponseInfo info; - std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" - "Content-Range: bytes " - "%" PRId64 "-%" PRId64 "/%" PRId64, - first_position, - last_position, - instance_size); - replace(header.begin(), header.end(), '\n', '\0'); - info.headers = new net::HttpResponseHeaders(header); - info.content_length = content_length; - loader_->OnReceivedResponse(info, false); - EXPECT_EQ(content_length, loader_->content_length()); - EXPECT_EQ(instance_size, loader_->instance_size()); - EXPECT_TRUE(loader_->partial_response()); - } - - void StopWhenLoad() { - InSequence s; - EXPECT_CALL(*bridge_, Cancel()) - .WillOnce(RequestCanceled(loader_)); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - loader_->Stop(); - } - - void ReleaseBridge() { - ignore_result(bridge_.release()); - } - - // Helper method to write to |loader_| from |data_|. - void WriteLoader(int position, int size) { - EXPECT_CALL(*this, NetworkCallback()) - .RetiresOnSaturation(); - loader_->OnReceivedData(reinterpret_cast(data_ + position), size); - } - - // Helper method to read from |loader_|. - void ReadLoader(int64 position, int size, uint8* buffer) { - loader_->Read(position, size, buffer, - NewCallback(this, &BufferedResourceLoaderTest::ReadCallback)); - } - - // Verifis that data in buffer[0...size] is equal to data_[pos...pos+size]. - void VerifyBuffer(uint8* buffer, int pos, int size) { - EXPECT_EQ(0, memcmp(buffer, data_ + pos, size)); - } - - // Helper method to disallow deferring in |loader_|. - void DisallowLoaderDefer() { - if (loader_->deferred_) { - EXPECT_CALL(*bridge_, SetDefersLoading(false)); - EXPECT_CALL(*this, NetworkCallback()); - } - loader_->SetAllowDefer(false); + MockBufferedDataSource( + MessageLoop* message_loop, WebFrame* frame) + : BufferedDataSource(message_loop, frame) { } - // Helper method to allow deferring in |loader_|. - void AllowLoaderDefer() { - loader_->SetAllowDefer(true); + virtual base::TimeDelta GetTimeoutMilliseconds() { + return base::TimeDelta::FromMilliseconds( + TestTimeouts::tiny_timeout_ms()); } - MOCK_METHOD1(StartCallback, void(int error)); - MOCK_METHOD1(ReadCallback, void(int error)); - MOCK_METHOD0(NetworkCallback, void()); - - protected: - GURL gurl_; - int64 first_position_; - int64 last_position_; - - scoped_refptr loader_; - StrictMock bridge_factory_; - scoped_ptr > bridge_; - - uint8 data_[kDataSize]; + MOCK_METHOD2(CreateResourceLoader, + BufferedResourceLoader*(int64 first_position, + int64 last_position)); private: - DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoaderTest); + DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource); }; -TEST_F(BufferedResourceLoaderTest, StartStop) { - Initialize(kHttpUrl, -1, -1); - Start(); - StopWhenLoad(); -} - -// Tests that HTTP header is missing in the response. -TEST_F(BufferedResourceLoaderTest, MissingHttpHeader) { - Initialize(kHttpUrl, -1, -1); - Start(); - - EXPECT_CALL(*this, StartCallback(net::ERR_INVALID_RESPONSE)); - EXPECT_CALL(*bridge_, Cancel()) - .WillOnce(RequestCanceled(loader_)); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - - ResourceResponseInfo info; - loader_->OnReceivedResponse(info, false); -} - -// Tests that a bad HTTP response is recived, e.g. file not found. -TEST_F(BufferedResourceLoaderTest, BadHttpResponse) { - Initialize(kHttpUrl, -1, -1); - Start(); - - EXPECT_CALL(*this, StartCallback(net::ERR_FAILED)); - EXPECT_CALL(*bridge_, Cancel()) - .WillOnce(RequestCanceled(loader_)); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - - ResourceResponseInfo info; - info.headers = new net::HttpResponseHeaders("HTTP/1.1 404 Not Found\n"); - loader_->OnReceivedResponse(info, false); -} - -// Tests that partial content is requested but not fulfilled. -TEST_F(BufferedResourceLoaderTest, NotPartialResponse) { - Initialize(kHttpUrl, 100, -1); - Start(); - FullResponse(1024); - StopWhenLoad(); -} - -// Tests that a 200 response is received. -TEST_F(BufferedResourceLoaderTest, FullResponse) { - Initialize(kHttpUrl, -1, -1); - Start(); - FullResponse(1024); - StopWhenLoad(); -} - -// Tests that a partial content response is received. -TEST_F(BufferedResourceLoaderTest, PartialResponse) { - Initialize(kHttpUrl, 100, 200); - Start(); - PartialResponse(100, 200, 1024); - StopWhenLoad(); -} - -// Tests that an invalid partial response is received. -TEST_F(BufferedResourceLoaderTest, InvalidPartialResponse) { - Initialize(kHttpUrl, 0, 10); - Start(); - - EXPECT_CALL(*this, StartCallback(net::ERR_INVALID_RESPONSE)); - EXPECT_CALL(*bridge_, Cancel()) - .WillOnce(RequestCanceled(loader_)); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - - ResourceResponseInfo info; - std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" - "Content-Range: bytes %d-%d/%d", - 1, 10, 1024); - replace(header.begin(), header.end(), '\n', '\0'); - info.headers = new net::HttpResponseHeaders(header); - info.content_length = 10; - loader_->OnReceivedResponse(info, false); -} - -// Tests the logic of sliding window for data buffering and reading. -TEST_F(BufferedResourceLoaderTest, BufferAndRead) { - Initialize(kHttpUrl, 10, 29); - Start(); - PartialResponse(10, 29, 30); - - uint8 buffer[10]; - InSequence s; - - // Writes 10 bytes and read them back. - WriteLoader(10, 10); - EXPECT_CALL(*this, ReadCallback(10)); - ReadLoader(10, 10, buffer); - VerifyBuffer(buffer, 10, 10); - - // Writes 10 bytes and read 2 times. - WriteLoader(20, 10); - EXPECT_CALL(*this, ReadCallback(5)); - ReadLoader(20, 5, buffer); - VerifyBuffer(buffer, 20, 5); - EXPECT_CALL(*this, ReadCallback(5)); - ReadLoader(25, 5, buffer); - VerifyBuffer(buffer, 25, 5); - - // Read backward within buffer. - EXPECT_CALL(*this, ReadCallback(10)); - ReadLoader(10, 10, buffer); - VerifyBuffer(buffer, 10, 10); - - // Read backward outside buffer. - EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); - ReadLoader(9, 10, buffer); - - // Response has completed. - EXPECT_CALL(*this, NetworkCallback()); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - URLRequestStatus status; - status.set_status(URLRequestStatus::SUCCESS); - loader_->OnCompletedRequest(status, "", base::Time()); - - // Try to read 10 from position 25 will just return with 5 bytes. - EXPECT_CALL(*this, ReadCallback(5)); - ReadLoader(25, 10, buffer); - VerifyBuffer(buffer, 25, 5); - - // Try to read outside buffered range after request has completed. - EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); - ReadLoader(5, 10, buffer); - - // Try to read beyond the instance size. - EXPECT_CALL(*this, ReadCallback(0)); - ReadLoader(30, 10, buffer); -} - -TEST_F(BufferedResourceLoaderTest, ReadOutsideBuffer) { - Initialize(kHttpUrl, 10, 0x00FFFFFF); - Start(); - PartialResponse(10, 0x00FFFFFF, 0x01000000); - - uint8 buffer[10]; - InSequence s; - - // Read very far aheard will get a cache miss. - EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); - ReadLoader(0x00FFFFFF, 1, buffer); - - // The following call will not call ReadCallback() because it is waiting for - // data to arrive. - ReadLoader(10, 10, buffer); - - // Writing to loader will fulfill the read request. - EXPECT_CALL(*this, ReadCallback(10)); - WriteLoader(10, 20); - VerifyBuffer(buffer, 10, 10); - - // The following call cannot be fulfilled now. - ReadLoader(25, 10, buffer); - - EXPECT_CALL(*this, ReadCallback(5)); - EXPECT_CALL(*this, NetworkCallback()); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - URLRequestStatus status; - status.set_status(URLRequestStatus::SUCCESS); - loader_->OnCompletedRequest(status, "", base::Time()); -} - -TEST_F(BufferedResourceLoaderTest, RequestFailedWhenRead) { - Initialize(kHttpUrl, 10, 29); - Start(); - PartialResponse(10, 29, 30); - - uint8 buffer[10]; - InSequence s; - - ReadLoader(10, 10, buffer); - EXPECT_CALL(*this, ReadCallback(net::ERR_FAILED)); - EXPECT_CALL(*this, NetworkCallback()); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - URLRequestStatus status; - status.set_status(URLRequestStatus::FAILED); - loader_->OnCompletedRequest(status, "", base::Time()); -} - -// Tests the logic of caching data to disk when media is paused. -TEST_F(BufferedResourceLoaderTest, AllowDefer_NoDataReceived) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - // Start in undeferred state, then disallow defer, then allow defer - // without receiving data in between. - DisallowLoaderDefer(); - AllowLoaderDefer(); - StopWhenLoad(); -} - -TEST_F(BufferedResourceLoaderTest, AllowDefer_ReadSameWindow) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - uint8 buffer[10]; - - // Start in undeferred state, disallow defer, receive data but don't shift - // buffer window, then allow defer and read. - DisallowLoaderDefer(); - WriteLoader(10, 10); - AllowLoaderDefer(); - - EXPECT_CALL(*this, ReadCallback(10)); - ReadLoader(10, 10, buffer); - VerifyBuffer(buffer, 10, 10); - StopWhenLoad(); -} - -TEST_F(BufferedResourceLoaderTest, AllowDefer_ReadPastWindow) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - uint8 buffer[10]; - - // Not deferred, disallow defer, received data and shift buffer window, - // allow defer, then read in area outside of buffer window. - DisallowLoaderDefer(); - WriteLoader(10, 10); - WriteLoader(20, 50); - AllowLoaderDefer(); - - EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); - ReadLoader(10, 10, buffer); - StopWhenLoad(); -} - -TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredNoDataReceived) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - uint8 buffer[10]; - - // Start in deferred state, then disallow defer, receive no data, and - // allow defer and read. - EXPECT_CALL(*bridge_, SetDefersLoading(true)); - EXPECT_CALL(*this, NetworkCallback()); - WriteLoader(10, 40); - - DisallowLoaderDefer(); - AllowLoaderDefer(); - - EXPECT_CALL(*this, ReadCallback(10)); - ReadLoader(20, 10, buffer); - VerifyBuffer(buffer, 20, 10); - StopWhenLoad(); -} - -TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredReadSameWindow) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - uint8 buffer[10]; - - // Start in deferred state, disallow defer, receive data and shift buffer - // window, allow defer, and read in a place that's still in the window. - EXPECT_CALL(*bridge_, SetDefersLoading(true)); - EXPECT_CALL(*this, NetworkCallback()); - WriteLoader(10, 30); - - DisallowLoaderDefer(); - WriteLoader(40, 5); - AllowLoaderDefer(); - - EXPECT_CALL(*this, ReadCallback(10)); - ReadLoader(20, 10, buffer); - VerifyBuffer(buffer, 20, 10); - StopWhenLoad(); -} - -TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredReadPastWindow) { - Initialize(kHttpUrl, 10, 99); - SetLoaderBuffer(10, 20); - Start(); - PartialResponse(10, 99, 100); - - uint8 buffer[10]; - - // Start in deferred state, disallow defer, receive data and shift buffer - // window, allow defer, and read outside of the buffer window. - EXPECT_CALL(*bridge_, SetDefersLoading(true)); - EXPECT_CALL(*this, NetworkCallback()); - WriteLoader(10, 40); - - DisallowLoaderDefer(); - WriteLoader(50, 20); - WriteLoader(70, 40); - AllowLoaderDefer(); - - EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); - ReadLoader(20, 5, buffer); - StopWhenLoad(); -} - -// TODO(hclam): add unit test for defer loading. - class MockBufferedResourceLoader : public BufferedResourceLoader { public: - MockBufferedResourceLoader() : BufferedResourceLoader(NULL, GURL(), 0, 0) { + MockBufferedResourceLoader() : BufferedResourceLoader(GURL(), 0, 0) { } - MOCK_METHOD2(Start, void(net::CompletionCallback* read_callback, - NetworkEventCallback* network_callback)); + MOCK_METHOD3(Start, void(net::CompletionCallback* read_callback, + NetworkEventCallback* network_callback, + WebFrame* frame)); MOCK_METHOD0(Stop, void()); MOCK_METHOD4(Read, void(int64 position, int read_size, uint8* buffer, net::CompletionCallback* callback)); @@ -536,33 +92,10 @@ class MockBufferedResourceLoader : public BufferedResourceLoader { DISALLOW_COPY_AND_ASSIGN(MockBufferedResourceLoader); }; -// A mock BufferedDataSource to inject mock BufferedResourceLoader through -// CreateResourceLoader() method. -class MockBufferedDataSource : public BufferedDataSource { - public: - MockBufferedDataSource( - MessageLoop* message_loop, MediaResourceLoaderBridgeFactory* factory) - : BufferedDataSource(message_loop, factory) { - } - - virtual base::TimeDelta GetTimeoutMilliseconds() { - // It is 100 ms because we don't want the test to run too long. - return base::TimeDelta::FromMilliseconds(100); - } - - MOCK_METHOD2(CreateResourceLoader, BufferedResourceLoader*( - int64 first_position, int64 last_position)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource); -}; - class BufferedDataSourceTest : public testing::Test { public: BufferedDataSourceTest() { message_loop_ = MessageLoop::current(); - bridge_factory_.reset( - new StrictMock()); // Prepare test data. for (size_t i = 0; i < sizeof(data_); ++i) { @@ -571,20 +104,14 @@ class BufferedDataSourceTest : public testing::Test { } virtual ~BufferedDataSourceTest() { - if (data_source_) { - // Release the bridge factory because we don't own it. - // Expects bridge factory to be destroyed along with data source. - EXPECT_CALL(*bridge_factory_, OnDestroy()) - .WillOnce(Invoke(this, - &BufferedDataSourceTest::ReleaseBridgeFactory)); - } + ignore_result(frame_.release()); } void ExpectCreateAndStartResourceLoader(int start_error) { EXPECT_CALL(*data_source_, CreateResourceLoader(_, _)) .WillOnce(Return(loader_.get())); - EXPECT_CALL(*loader_, Start(NotNull(), NotNull())) + EXPECT_CALL(*loader_, Start(NotNull(), NotNull(), NotNull())) .WillOnce( DoAll(Assign(&error_, start_error), Invoke(this, @@ -597,15 +124,10 @@ class BufferedDataSourceTest : public testing::Test { // Saves the url first. gurl_ = GURL(url); - media::MediaFormat url_format; - url_format.SetAsString(media::MediaFormat::kMimeType, - media::mime_type::kURL); - url_format.SetAsString(media::MediaFormat::kURL, url); - data_source_ = new MockBufferedDataSource(MessageLoop::current(), - bridge_factory_.get()); - CHECK(data_source_); + frame_.reset(new NiceMock()); - // There is no need to provide a message loop to data source. + data_source_ = new MockBufferedDataSource(MessageLoop::current(), + frame_.get()); data_source_->set_host(&host_); scoped_refptr > first_loader( @@ -631,7 +153,7 @@ class BufferedDataSourceTest : public testing::Test { // Replace loader_ with a new instance. loader_ = new NiceMock(); - // Create and start Make sure Start() is called the new loader. + // Create and start. Make sure Start() is called on the new loader. ExpectCreateAndStartResourceLoader(net::OK); // Update initialization variable since we know the second loader will @@ -705,13 +227,10 @@ class BufferedDataSourceTest : public testing::Test { message_loop_->RunAllPending(); } - void ReleaseBridgeFactory() { - ignore_result(bridge_factory_.release()); - } - void InvokeStartCallback( net::CompletionCallback* callback, - BufferedResourceLoader::NetworkEventCallback* network_callback) { + BufferedResourceLoader::NetworkEventCallback* network_callback, + WebFrame* frame) { callback->RunWithParams(Tuple1(error_)); delete callback; // TODO(hclam): Save this callback. @@ -790,7 +309,7 @@ class BufferedDataSourceTest : public testing::Test { .WillOnce(Return(new_loader)); // 3. Then the new loader will be started. - EXPECT_CALL(*new_loader, Start(NotNull(), NotNull())) + EXPECT_CALL(*new_loader, Start(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(Assign(&error_, net::OK), Invoke(this, &BufferedDataSourceTest::InvokeStartCallback))); @@ -856,7 +375,7 @@ class BufferedDataSourceTest : public testing::Test { // 3. Then the new loader will be started and respond to queries about // whether this is a partial response using the value of the previous // loader. - EXPECT_CALL(*new_loader, Start(NotNull(), NotNull())) + EXPECT_CALL(*new_loader, Start(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(Assign(&error_, net::OK), Invoke(this, &BufferedDataSourceTest::InvokeStartCallback))); @@ -889,10 +408,9 @@ class BufferedDataSourceTest : public testing::Test { MOCK_METHOD1(ReadCallback, void(size_t size)); - scoped_ptr > - bridge_factory_; scoped_refptr > loader_; scoped_refptr data_source_; + scoped_ptr > frame_; StrictMock host_; GURL gurl_; diff --git a/webkit/glue/media/buffered_resource_loader.cc b/webkit/glue/media/buffered_resource_loader.cc new file mode 100644 index 0000000..61aac72 --- /dev/null +++ b/webkit/glue/media/buffered_resource_loader.cc @@ -0,0 +1,578 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/media/buffered_resource_loader.h" + +#include "base/format_macros.h" +#include "base/string_util.h" +#include "net/base/net_errors.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "webkit/glue/multipart_response_delegate.h" +#include "webkit/glue/webkit_glue.h" + +using WebKit::WebFrame; +using WebKit::WebString; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; +using webkit_glue::MultipartResponseDelegate; + +namespace { + +const int kHttpOK = 200; +const int kHttpPartialContent = 206; + +// Define the number of bytes in a megabyte. +const size_t kMegabyte = 1024 * 1024; + +// Backward capacity of the buffer, by default 2MB. +const size_t kBackwardCapcity = 2 * kMegabyte; + +// Forward capacity of the buffer, by default 10MB. +const size_t kForwardCapacity = 10 * kMegabyte; + +// The threshold of bytes that we should wait until the data arrives in the +// future instead of restarting a new connection. This number is defined in the +// number of bytes, we should determine this value from typical connection speed +// and amount of time for a suitable wait. Now I just make a guess for this +// number to be 2MB. +// TODO(hclam): determine a better value for this. +const int kForwardWaitThreshold = 2 * kMegabyte; + +} // namespace + +namespace webkit_glue { + +BufferedResourceLoader::BufferedResourceLoader( + const GURL& url, + int64 first_byte_position, + int64 last_byte_position) + : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), + deferred_(false), + defer_allowed_(true), + completed_(false), + range_requested_(false), + partial_response_(false), + url_(url), + first_byte_position_(first_byte_position), + last_byte_position_(last_byte_position), + start_callback_(NULL), + offset_(0), + content_length_(kPositionNotSpecified), + instance_size_(kPositionNotSpecified), + read_callback_(NULL), + read_position_(0), + read_size_(0), + read_buffer_(NULL), + first_offset_(0), + last_offset_(0), + keep_test_loader_(false) { +} + +BufferedResourceLoader::~BufferedResourceLoader() { + if (!completed_ && url_loader_.get()) + url_loader_->cancel(); +} + +void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, + NetworkEventCallback* event_callback, + WebFrame* frame) { + // Make sure we have not started. + DCHECK(!start_callback_.get()); + DCHECK(!event_callback_.get()); + DCHECK(start_callback); + DCHECK(event_callback); + CHECK(frame); + + start_callback_.reset(start_callback); + event_callback_.reset(event_callback); + + if (first_byte_position_ != kPositionNotSpecified) { + range_requested_ = true; + // TODO(hclam): server may not support range request so |offset_| may not + // equal to |first_byte_position_|. + offset_ = first_byte_position_; + } + + // Increment the reference count right before we start the request. This + // reference will be release when this request has ended. + AddRef(); + + // Prepare the request. + WebURLRequest request(url_); + request.setTargetType(WebURLRequest::TargetIsMedia); + request.setHTTPHeaderField(WebString::fromUTF8("Range"), + WebString::fromUTF8(GenerateHeaders( + first_byte_position_, + last_byte_position_))); + frame->setReferrerForRequest(request, WebKit::WebURL()); + + // This flag is for unittests as we don't want to reset |url_loader| + if (!keep_test_loader_) + url_loader_.reset(frame->createAssociatedURLLoader()); + + // Start the resource loading. + url_loader_->loadAsynchronously(request, this); +} + +void BufferedResourceLoader::Stop() { + // Reset callbacks. + start_callback_.reset(); + event_callback_.reset(); + read_callback_.reset(); + + // Use the internal buffer to signal that we have been stopped. + // TODO(hclam): Not so pretty to do this. + if (!buffer_.get()) + return; + + // Destroy internal buffer. + buffer_.reset(); + + if (url_loader_.get()) { + if (deferred_) + url_loader_->setDefersLoading(false); + deferred_ = false; + + if (!completed_) { + url_loader_->cancel(); + completed_ = true; + } + } +} + +void BufferedResourceLoader::Read(int64 position, + int read_size, + uint8* buffer, + net::CompletionCallback* read_callback) { + DCHECK(!read_callback_.get()); + DCHECK(buffer_.get()); + DCHECK(read_callback); + DCHECK(buffer); + + // Save the parameter of reading. + read_callback_.reset(read_callback); + read_position_ = position; + read_size_ = read_size; + read_buffer_ = buffer; + + // If read position is beyond the instance size, we cannot read there. + if (instance_size_ != kPositionNotSpecified && + instance_size_ <= read_position_) { + DoneRead(0); + return; + } + + // Make sure |offset_| and |read_position_| does not differ by a large + // amount. + if (read_position_ > offset_ + kint32max || + read_position_ < offset_ + kint32min) { + DoneRead(net::ERR_CACHE_MISS); + return; + } + + // Prepare the parameters. + first_offset_ = static_cast(read_position_ - offset_); + last_offset_ = first_offset_ + read_size_; + + // If we can serve the request now, do the actual read. + if (CanFulfillRead()) { + ReadInternal(); + DisableDeferIfNeeded(); + return; + } + + // If we expected the read request to be fulfilled later, returns + // immediately and let more data to flow in. + if (WillFulfillRead()) + return; + + // Make a callback to report failure. + DoneRead(net::ERR_CACHE_MISS); +} + +int64 BufferedResourceLoader::GetBufferedPosition() { + if (buffer_.get()) + return offset_ + static_cast(buffer_->forward_bytes()) - 1; + return kPositionNotSpecified; +} + +void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { + defer_allowed_ = is_allowed; + DisableDeferIfNeeded(); +} + +int64 BufferedResourceLoader::content_length() { + return content_length_; +} + +int64 BufferedResourceLoader::instance_size() { + return instance_size_; +} + +bool BufferedResourceLoader::partial_response() { + return partial_response_; +} + +bool BufferedResourceLoader::network_activity() { + return !completed_ && !deferred_; +} + +const GURL& BufferedResourceLoader::url() { + return url_; +} + +void BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* mock_loader) { + url_loader_.reset(mock_loader); + keep_test_loader_ = true; +} + +///////////////////////////////////////////////////////////////////////////// +// WebKit::WebURLLoaderClient implementation. +void BufferedResourceLoader::willSendRequest( + WebURLLoader* loader, + WebURLRequest& newRequest, + const WebURLResponse& redirectResponse) { + + // The load may have been stopped and |start_callback| is destroyed. + // In this case we shouldn't do anything. + if (!start_callback_.get()) { + // Set the url in the request to an invalid value (empty url). + newRequest.setURL(WebKit::WebURL()); + return; + } + + if (!IsProtocolSupportedForMedia(newRequest.url())) { + // Set the url in the request to an invalid value (empty url). + newRequest.setURL(WebKit::WebURL()); + DoneStart(net::ERR_ADDRESS_INVALID); + Stop(); + return; + } + + url_ = newRequest.url(); +} + +void BufferedResourceLoader::didSendData( + WebURLLoader* loader, + unsigned long long bytes_sent, + unsigned long long total_bytes_to_be_sent) { + NOTIMPLEMENTED(); +} + +void BufferedResourceLoader::didReceiveResponse( + WebURLLoader* loader, + const WebURLResponse& response) { + + // The loader may have been stopped and |start_callback| is destroyed. + // In this case we shouldn't do anything. + if (!start_callback_.get()) + return; + + // We make a strong assumption that when we reach here we have either + // received a response from HTTP/HTTPS protocol or the request was + // successful (in particular range request). So we only verify the partial + // response for HTTP and HTTPS protocol. + if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { + int error = net::OK; + + if (response.httpStatusCode() == kHttpPartialContent) + partial_response_ = true; + + if (range_requested_ && partial_response_) { + // If we have verified the partial response and it is correct, we will + // return net::OK. + if (!VerifyPartialResponse(response)) + error = net::ERR_INVALID_RESPONSE; + } else if (response.httpStatusCode() != kHttpOK) { + // We didn't request a range but server didn't reply with "200 OK". + error = net::ERR_FAILED; + } + + if (error != net::OK) { + DoneStart(error); + Stop(); + return; + } + } else { + // For any protocol other than HTTP and HTTPS, assume range request is + // always fulfilled. + partial_response_ = range_requested_; + } + + // Expected content length can be |kPositionNotSpecified|, in that case + // |content_length_| is not specified and this is a streaming response. + content_length_ = response.expectedContentLength(); + + // If we have not requested a range, then the size of the instance is equal + // to the content length. + if (!partial_response_) + instance_size_ = content_length_; + + // Calls with a successful response. + DoneStart(net::OK); +} + +void BufferedResourceLoader::didReceiveData( + WebURLLoader* loader, + const char* data, + int data_length) { + DCHECK(!completed_); + DCHECK_GT(data_length, 0); + + // If this loader has been stopped, |buffer_| would be destroyed. + // In this case we shouldn't do anything. + if (!buffer_.get()) + return; + + // Writes more data to |buffer_|. + buffer_->Append(reinterpret_cast(data), data_length); + + // If there is an active read request, try to fulfill the request. + if (HasPendingRead() && CanFulfillRead()) { + ReadInternal(); + } else if (!defer_allowed_) { + // If we're not allowed to defer, slide the buffer window forward instead + // of deferring. + if (buffer_->forward_bytes() > buffer_->forward_capacity()) { + size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); + bool success = buffer_->Seek(excess); + DCHECK(success); + offset_ += first_offset_ + excess; + } + } + + // At last see if the buffer is full and we need to defer the downloading. + EnableDeferIfNeeded(); + + // Notify that we have received some data. + NotifyNetworkEvent(); +} + +void BufferedResourceLoader::didDownloadData( + WebKit::WebURLLoader* loader, + int dataLength) { + NOTIMPLEMENTED(); +} + +void BufferedResourceLoader::didReceiveCachedMetadata( + WebURLLoader* loader, + const char* data, + int data_length) { + NOTIMPLEMENTED(); +} + +void BufferedResourceLoader::didFinishLoading( + WebURLLoader* loader, + double finishTime) { + DCHECK(!completed_); + completed_ = true; + + // If there is a start callback, calls it. + if (start_callback_.get()) { + DoneStart(net::OK); + } + + // If there is a pending read but the request has ended, returns with what + // we have. + if (HasPendingRead()) { + // Make sure we have a valid buffer before we satisfy a read request. + DCHECK(buffer_.get()); + + // Try to fulfill with what is in the buffer. + if (CanFulfillRead()) + ReadInternal(); + else + DoneRead(net::ERR_CACHE_MISS); + } + + // There must not be any outstanding read request. + DCHECK(!HasPendingRead()); + + // Notify that network response is completed. + NotifyNetworkEvent(); + + url_loader_.reset(); + Release(); +} + +void BufferedResourceLoader::didFail( + WebURLLoader* loader, + const WebURLError& error) { + DCHECK(!completed_); + completed_ = true; + + // If there is a start callback, calls it. + if (start_callback_.get()) { + DoneStart(error.reason); + } + + // If there is a pending read but the request failed, return with the + // reason for the error. + if (HasPendingRead()) { + DoneRead(error.reason); + } + + // Notify that network response is completed. + NotifyNetworkEvent(); + + url_loader_.reset(); + Release(); +} + +///////////////////////////////////////////////////////////////////////////// +// Helper methods. +void BufferedResourceLoader::EnableDeferIfNeeded() { + if (!defer_allowed_) + return; + + if (!deferred_ && + buffer_->forward_bytes() >= buffer_->forward_capacity()) { + deferred_ = true; + + if (url_loader_.get()) + url_loader_->setDefersLoading(true); + + NotifyNetworkEvent(); + } +} + +void BufferedResourceLoader::DisableDeferIfNeeded() { + if (deferred_ && + (!defer_allowed_ || + buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { + deferred_ = false; + + if (url_loader_.get()) + url_loader_->setDefersLoading(false); + + NotifyNetworkEvent(); + } +} + +bool BufferedResourceLoader::CanFulfillRead() { + // If we are reading too far in the backward direction. + if (first_offset_ < 0 && + first_offset_ + static_cast(buffer_->backward_bytes()) < 0) + return false; + + // If the start offset is too far ahead. + if (first_offset_ >= static_cast(buffer_->forward_bytes())) + return false; + + // At the point, we verified that first byte requested is within the buffer. + // If the request has completed, then just returns with what we have now. + if (completed_) + return true; + + // If the resource request is still active, make sure the whole requested + // range is covered. + if (last_offset_ > static_cast(buffer_->forward_bytes())) + return false; + + return true; +} + +bool BufferedResourceLoader::WillFulfillRead() { + // Reading too far in the backward direction. + if (first_offset_ < 0 && + first_offset_ + static_cast(buffer_->backward_bytes()) < 0) + return false; + + // Try to read too far ahead. + if (last_offset_ > kForwardWaitThreshold) + return false; + + // The resource request has completed, there's no way we can fulfill the + // read request. + if (completed_) + return false; + + return true; +} + +void BufferedResourceLoader::ReadInternal() { + // Seek to the first byte requested. + bool ret = buffer_->Seek(first_offset_); + DCHECK(ret); + + // Then do the read. + int read = static_cast(buffer_->Read(read_buffer_, read_size_)); + offset_ += first_offset_ + read; + + // And report with what we have read. + DoneRead(read); +} + +bool BufferedResourceLoader::VerifyPartialResponse( + const WebURLResponse& response) { + int first_byte_position, last_byte_position, instance_size; + + if (!MultipartResponseDelegate::ReadContentRanges(response, + &first_byte_position, + &last_byte_position, + &instance_size)) { + return false; + } + + if (instance_size != kPositionNotSpecified) { + instance_size_ = instance_size; + } + + if (first_byte_position_ != kPositionNotSpecified && + first_byte_position_ != first_byte_position) { + return false; + } + + // TODO(hclam): I should also check |last_byte_position|, but since + // we will never make such a request that it is ok to leave it unimplemented. + return true; +} + +std::string BufferedResourceLoader::GenerateHeaders( + int64 first_byte_position, + int64 last_byte_position) { + // Construct the value for the range header. + std::string header; + if (first_byte_position > kPositionNotSpecified && + last_byte_position > kPositionNotSpecified) { + if (first_byte_position <= last_byte_position) { + header = base::StringPrintf("bytes=%" PRId64 "-%" PRId64, + first_byte_position, + last_byte_position); + } + } else if (first_byte_position > kPositionNotSpecified) { + header = base::StringPrintf("bytes=%" PRId64 "-", + first_byte_position); + } else if (last_byte_position > kPositionNotSpecified) { + NOTIMPLEMENTED() << "Suffix range not implemented"; + } + return header; +} + +void BufferedResourceLoader::DoneRead(int error) { + read_callback_->RunWithParams(Tuple1(error)); + read_callback_.reset(); + read_position_ = 0; + read_size_ = 0; + read_buffer_ = NULL; + first_offset_ = 0; + last_offset_ = 0; +} + +void BufferedResourceLoader::DoneStart(int error) { + start_callback_->RunWithParams(Tuple1(error)); + start_callback_.reset(); +} + +void BufferedResourceLoader::NotifyNetworkEvent() { + if (event_callback_.get()) + event_callback_->Run(); +} + +} // namespace webkit_glue diff --git a/webkit/glue/media/buffered_resource_loader.h b/webkit/glue/media/buffered_resource_loader.h new file mode 100644 index 0000000..09b05e6 --- /dev/null +++ b/webkit/glue/media/buffered_resource_loader.h @@ -0,0 +1,246 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_MEDIA_BUFFERED_RESOURCE_LOADER_H_ +#define WEBKIT_GLUE_MEDIA_BUFFERED_RESOURCE_LOADER_H_ + +#include + +#include "base/callback.h" +#include "base/lock.h" +#include "base/scoped_ptr.h" +#include "base/timer.h" +#include "googleurl/src/gurl.h" +#include "media/base/seekable_buffer.h" +#include "net/base/file_stream.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "webkit/glue/media/web_data_source.h" +#include "webkit/glue/webmediaplayer_impl.h" + +namespace webkit_glue { + +const int64 kPositionNotSpecified = -1; + +const char kHttpScheme[] = "http"; +const char kHttpsScheme[] = "https"; +const char kDataScheme[] = "data"; + +// This class works inside demuxer thread and render thread. It contains a +// WebURLLoader and does the actual resource loading. This object does +// buffering internally, it defers the resource loading if buffer is full +// and un-defers the resource loading if it is under buffered. +class BufferedResourceLoader : + public base::RefCountedThreadSafe, + public WebKit::WebURLLoaderClient { + public: + typedef Callback0::Type NetworkEventCallback; + + // |url| - URL for the resource to be loaded. + // |first_byte_position| - First byte to start loading from, + // |kPositionNotSpecified| for not specified. + // |last_byte_position| - Last byte to be loaded, + // |kPositionNotSpecified| for not specified. + BufferedResourceLoader(const GURL& url, + int64 first_byte_position, + int64 last_byte_position); + + // Start the resource loading with the specified URL and range. + // This method operates in asynchronous mode. Once there's a response from the + // server, success or fail |callback| is called with the result. + // |callback| is called with the following values: + // - net::OK + // The request has started successfully. + // - net::ERR_FAILED + // The request has failed because of an error with the network. + // - net::ERR_INVALID_RESPONSE + // An invalid response is received from the server. + // - (Anything else) + // An error code that indicates the request has failed. + // |event_callback| is called when the response is completed, data is + // received, the request is suspended or resumed. + virtual void Start(net::CompletionCallback* callback, + NetworkEventCallback* event_callback, + WebKit::WebFrame* frame); + + // Stop this loader, cancels and request and release internal buffer. + virtual void Stop(); + + // Reads the specified |read_size| from |position| into |buffer| and when + // the operation is done invoke |callback| with number of bytes read or an + // error code. + // |callback| is called with the following values: + // - (Anything greater than or equal 0) + // Read was successful with the indicated number of bytes read. + // - net::ERR_FAILED + // The read has failed because of an error with the network. + // - net::ERR_CACHE_MISS + // The read was made too far away from the current buffered position. + virtual void Read(int64 position, int read_size, + uint8* buffer, net::CompletionCallback* callback); + + // Returns the position of the last byte buffered. Returns + // |kPositionNotSpecified| if such value is not available. + virtual int64 GetBufferedPosition(); + + // Sets whether deferring data is allowed or disallowed. + virtual void SetAllowDefer(bool is_allowed); + + // Gets the content length in bytes of the instance after this loader has been + // started. If this value is |kPositionNotSpecified|, then content length is + // unknown. + virtual int64 content_length(); + + // Gets the original size of the file requested. If this value is + // |kPositionNotSpecified|, then the size is unknown. + virtual int64 instance_size(); + + // Returns true if the response for this loader is a partial response. + // It means a 206 response in HTTP/HTTPS protocol. + virtual bool partial_response(); + + // Returns true if network is currently active. + virtual bool network_activity(); + + // Returns resulting URL. + virtual const GURL& url(); + + // Used to inject a mock used for unittests. + virtual void SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader); + + // WebKit::WebURLLoaderClient implementation. + virtual void willSendRequest( + WebKit::WebURLLoader* loader, + WebKit::WebURLRequest& newRequest, + const WebKit::WebURLResponse& redirectResponse); + virtual void didSendData( + WebKit::WebURLLoader* loader, + unsigned long long bytesSent, + unsigned long long totalBytesToBeSent); + virtual void didReceiveResponse( + WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response); + virtual void didDownloadData( + WebKit::WebURLLoader* loader, + int dataLength); + virtual void didReceiveData( + WebKit::WebURLLoader* loader, + const char* data, + int dataLength); + virtual void didReceiveCachedMetadata( + WebKit::WebURLLoader* loader, + const char* data, int dataLength); + virtual void didFinishLoading( + WebKit::WebURLLoader* loader, + double finishTime); + virtual void didFail( + WebKit::WebURLLoader* loader, + const WebKit::WebURLError&); + + protected: + friend class base::RefCountedThreadSafe; + + virtual ~BufferedResourceLoader(); + + private: + friend class BufferedResourceLoaderTest; + + // Defer the resource loading if the buffer is full. + void EnableDeferIfNeeded(); + + // Disable defer loading if we are under-buffered. + void DisableDeferIfNeeded(); + + // Returns true if the current read request can be fulfilled by what is in + // the buffer. + bool CanFulfillRead(); + + // Returns true if the current read request will be fulfilled in the future. + bool WillFulfillRead(); + + // Method that does the actual read and calls the |read_callback_|, assuming + // the request range is in |buffer_|. + void ReadInternal(); + + // If we have made a range request, verify the response from the server. + bool VerifyPartialResponse(const WebKit::WebURLResponse& response); + + // Returns the value for a range request header using parameters + // |first_byte_position| and |last_byte_position|. Negative numbers other + // than |kPositionNotSpecified| are not allowed for |first_byte_position| and + // |last_byte_position|. |first_byte_position| should always be less than or + // equal to |last_byte_position| if they are both not |kPositionNotSpecified|. + // Empty string is returned on invalid parameters. + std::string GenerateHeaders(int64 first_byte_position, + int64 last_byte_position); + + // Done with read. Invokes the read callback and reset parameters for the + // read request. + void DoneRead(int error); + + // Done with start. Invokes the start callback and reset it. + void DoneStart(int error); + + // Calls |event_callback_| in terms of a network event. + void NotifyNetworkEvent(); + + bool HasPendingRead() { return read_callback_.get() != NULL; } + + // A sliding window of buffer. + scoped_ptr buffer_; + + // True if resource loading was deferred. + bool deferred_; + + // True if resource loader is allowed to defer, false otherwise. + bool defer_allowed_; + + // True if resource loading has completed. + bool completed_; + + // True if a range request was made. + bool range_requested_; + + // True if response data received is a partial range. + bool partial_response_; + + // Does the work of loading and sends data back to this client. + scoped_ptr url_loader_; + + GURL url_; + int64 first_byte_position_; + int64 last_byte_position_; + + // Callback method that listens to network events. + scoped_ptr event_callback_; + + // Members used during request start. + scoped_ptr start_callback_; + int64 offset_; + int64 content_length_; + int64 instance_size_; + + // Members used during a read operation. They should be reset after each + // read has completed or failed. + scoped_ptr read_callback_; + int64 read_position_; + int read_size_; + uint8* read_buffer_; + + // Offsets of the requested first byte and last byte in |buffer_|. They are + // written by Read(). + int first_offset_; + int last_offset_; + + // Used to ensure mocks for unittests are used instead of reset in Start(). + bool keep_test_loader_; + + DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_MEDIA_BUFFERED_RESOURCE_LOADER_H_ diff --git a/webkit/glue/media/buffered_resource_loader_unittest.cc b/webkit/glue/media/buffered_resource_loader_unittest.cc new file mode 100644 index 0000000..8e64c26 --- /dev/null +++ b/webkit/glue/media/buffered_resource_loader_unittest.cc @@ -0,0 +1,486 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include "base/format_macros.h" +#include "base/stringprintf.h" +#include "net/base/net_errors.h" +#include "net/http/http_util.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" +#include "webkit/glue/media/buffered_resource_loader.h" +#include "webkit/mocks/mock_webframe.h" +#include "webkit/mocks/mock_weburlloader.h" + +using ::testing::_; +using ::testing::Assign; +using ::testing::AtLeast; +using ::testing::DeleteArg; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::NotNull; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SetArgumentPointee; +using ::testing::StrictMock; +using ::testing::NiceMock; +using ::testing::WithArgs; + +using WebKit::WebURLError; +using WebKit::WebFrameClient; +using WebKit::WebURLResponse; +using WebKit::WebView; + +namespace { + +const char* kHttpUrl = "http://test"; +const int kDataSize = 1024; +const int kHttpOK = 200; +const int kHttpPartialContent = 206; + +enum NetworkState { + NONE, + LOADED, + LOADING +}; + +} // namespace + +namespace webkit_glue { + +// Submit a request completed event to the resource loader due to request +// being canceled. Pretending the event is from external. +ACTION_P(RequestCanceled, loader) { + WebURLError error; + error.reason = net::ERR_ABORTED; + error.domain = WebString::fromUTF8(net::kErrorDomain); + loader->didFail(NULL, error); +} + +class BufferedResourceLoaderTest : public testing::Test { + public: + BufferedResourceLoaderTest() { + url_loader_ = new NiceMock(); + + for (int i = 0; i < kDataSize; ++i) + data_[i] = i; + } + + virtual ~BufferedResourceLoaderTest() { + ignore_result(frame_.release()); + } + + void Initialize(const char* url, int first_position, int last_position) { + gurl_ = GURL(url); + first_position_ = first_position; + last_position_ = last_position; + + frame_.reset(new NiceMock()); + + loader_ = new BufferedResourceLoader(gurl_, + first_position_, last_position_); + loader_->SetURLLoaderForTest(url_loader_); + } + + void SetLoaderBuffer(size_t forward_capacity, size_t backward_capacity) { + loader_->buffer_.reset( + new media::SeekableBuffer(backward_capacity, forward_capacity)); + } + + void Start() { + InSequence s; + EXPECT_CALL(*url_loader_, loadAsynchronously(_, loader_.get())); + loader_->Start( + NewCallback(this, &BufferedResourceLoaderTest::StartCallback), + NewCallback(this, &BufferedResourceLoaderTest::NetworkCallback), + frame_.get()); + } + + void FullResponse(int64 instance_size) { + EXPECT_CALL(*this, StartCallback(net::OK)); + + WebURLResponse response(gurl_); + response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), + WebString::fromUTF8(base::StringPrintf("%" + PRId64, instance_size))); + response.setExpectedContentLength(instance_size); + response.setHTTPStatusCode(kHttpOK); + loader_->didReceiveResponse(url_loader_, response); + EXPECT_EQ(instance_size, loader_->content_length()); + EXPECT_EQ(instance_size, loader_->instance_size()); + EXPECT_FALSE(loader_->partial_response()); + } + + void PartialResponse(int64 first_position, int64 last_position, + int64 instance_size) { + EXPECT_CALL(*this, StartCallback(net::OK)); + int64 content_length = last_position - first_position + 1; + + WebURLResponse response(gurl_); + response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"), + WebString::fromUTF8(base::StringPrintf("bytes " + "%" PRId64 "-%" PRId64 "/%" PRId64, + first_position, + last_position, + instance_size))); + response.setExpectedContentLength(content_length); + response.setHTTPStatusCode(kHttpPartialContent); + loader_->didReceiveResponse(url_loader_, response); + EXPECT_EQ(content_length, loader_->content_length()); + EXPECT_EQ(instance_size, loader_->instance_size()); + EXPECT_TRUE(loader_->partial_response()); + } + + void StopWhenLoad() { + InSequence s; + EXPECT_CALL(*url_loader_, cancel()) + .WillOnce(RequestCanceled(loader_)); + loader_->Stop(); + } + + // Helper method to write to |loader_| from |data_|. + void WriteLoader(int position, int size) { + EXPECT_CALL(*this, NetworkCallback()) + .RetiresOnSaturation(); + loader_->didReceiveData(url_loader_, + reinterpret_cast(data_ + position), size); + } + + // Helper method to read from |loader_|. + void ReadLoader(int64 position, int size, uint8* buffer) { + loader_->Read(position, size, buffer, + NewCallback(this, &BufferedResourceLoaderTest::ReadCallback)); + } + + // Verifis that data in buffer[0...size] is equal to data_[pos...pos+size]. + void VerifyBuffer(uint8* buffer, int pos, int size) { + EXPECT_EQ(0, memcmp(buffer, data_ + pos, size)); + } + + // Helper method to disallow deferring in |loader_|. + void DisallowLoaderDefer() { + if (loader_->deferred_) { + EXPECT_CALL(*url_loader_, setDefersLoading(false)); + EXPECT_CALL(*this, NetworkCallback()); + } + loader_->SetAllowDefer(false); + } + + // Helper method to allow deferring in |loader_|. + void AllowLoaderDefer() { + loader_->SetAllowDefer(true); + } + + MOCK_METHOD1(StartCallback, void(int error)); + MOCK_METHOD1(ReadCallback, void(int error)); + MOCK_METHOD0(NetworkCallback, void()); + + protected: + GURL gurl_; + int64 first_position_; + int64 last_position_; + + scoped_refptr loader_; + NiceMock* url_loader_; + scoped_ptr > frame_; + + uint8 data_[kDataSize]; + + private: + DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoaderTest); +}; + +TEST_F(BufferedResourceLoaderTest, StartStop) { + Initialize(kHttpUrl, -1, -1); + Start(); + StopWhenLoad(); +} + +// Tests that a bad HTTP response is recived, e.g. file not found. +TEST_F(BufferedResourceLoaderTest, BadHttpResponse) { + Initialize(kHttpUrl, -1, -1); + Start(); + + EXPECT_CALL(*this, StartCallback(net::ERR_FAILED)); + EXPECT_CALL(*url_loader_, cancel()) + .WillOnce(RequestCanceled(loader_)); + + WebURLResponse response(gurl_); + response.setHTTPStatusCode(404); + response.setHTTPStatusText("Not Found\n"); + loader_->didReceiveResponse(url_loader_, response); +} + +// Tests that partial content is requested but not fulfilled. +TEST_F(BufferedResourceLoaderTest, NotPartialResponse) { + Initialize(kHttpUrl, 100, -1); + Start(); + FullResponse(1024); + StopWhenLoad(); +} + +// Tests that a 200 response is received. +TEST_F(BufferedResourceLoaderTest, FullResponse) { + Initialize(kHttpUrl, -1, -1); + Start(); + FullResponse(1024); + StopWhenLoad(); +} + +// Tests that a partial content response is received. +TEST_F(BufferedResourceLoaderTest, PartialResponse) { + Initialize(kHttpUrl, 100, 200); + Start(); + PartialResponse(100, 200, 1024); + StopWhenLoad(); +} + +// Tests that an invalid partial response is received. +TEST_F(BufferedResourceLoaderTest, InvalidPartialResponse) { + Initialize(kHttpUrl, 0, 10); + Start(); + + EXPECT_CALL(*this, StartCallback(net::ERR_INVALID_RESPONSE)); + EXPECT_CALL(*url_loader_, cancel()) + .WillOnce(RequestCanceled(loader_)); + + WebURLResponse response(gurl_); + response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"), + WebString::fromUTF8(base::StringPrintf("bytes " + "%d-%d/%d", 1, 10, 1024))); + response.setExpectedContentLength(10); + response.setHTTPStatusCode(kHttpPartialContent); + loader_->didReceiveResponse(url_loader_, response); +} + +// Tests the logic of sliding window for data buffering and reading. +TEST_F(BufferedResourceLoaderTest, BufferAndRead) { + Initialize(kHttpUrl, 10, 29); + Start(); + PartialResponse(10, 29, 30); + + uint8 buffer[10]; + InSequence s; + + // Writes 10 bytes and read them back. + WriteLoader(10, 10); + EXPECT_CALL(*this, ReadCallback(10)); + ReadLoader(10, 10, buffer); + VerifyBuffer(buffer, 10, 10); + + // Writes 10 bytes and read 2 times. + WriteLoader(20, 10); + EXPECT_CALL(*this, ReadCallback(5)); + ReadLoader(20, 5, buffer); + VerifyBuffer(buffer, 20, 5); + EXPECT_CALL(*this, ReadCallback(5)); + ReadLoader(25, 5, buffer); + VerifyBuffer(buffer, 25, 5); + + // Read backward within buffer. + EXPECT_CALL(*this, ReadCallback(10)); + ReadLoader(10, 10, buffer); + VerifyBuffer(buffer, 10, 10); + + // Read backward outside buffer. + EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); + ReadLoader(9, 10, buffer); + + // Response has completed. + EXPECT_CALL(*this, NetworkCallback()); + loader_->didFinishLoading(url_loader_, 0); + + // Try to read 10 from position 25 will just return with 5 bytes. + EXPECT_CALL(*this, ReadCallback(5)); + ReadLoader(25, 10, buffer); + VerifyBuffer(buffer, 25, 5); + + // Try to read outside buffered range after request has completed. + EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); + ReadLoader(5, 10, buffer); + + // Try to read beyond the instance size. + EXPECT_CALL(*this, ReadCallback(0)); + ReadLoader(30, 10, buffer); +} + +TEST_F(BufferedResourceLoaderTest, ReadOutsideBuffer) { + Initialize(kHttpUrl, 10, 0x00FFFFFF); + Start(); + PartialResponse(10, 0x00FFFFFF, 0x01000000); + + uint8 buffer[10]; + InSequence s; + + // Read very far aheard will get a cache miss. + EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); + ReadLoader(0x00FFFFFF, 1, buffer); + + // The following call will not call ReadCallback() because it is waiting for + // data to arrive. + ReadLoader(10, 10, buffer); + + // Writing to loader will fulfill the read request. + EXPECT_CALL(*this, ReadCallback(10)); + WriteLoader(10, 20); + VerifyBuffer(buffer, 10, 10); + + // The following call cannot be fulfilled now. + ReadLoader(25, 10, buffer); + + EXPECT_CALL(*this, ReadCallback(5)); + EXPECT_CALL(*this, NetworkCallback()); + loader_->didFinishLoading(url_loader_, 0); +} + +TEST_F(BufferedResourceLoaderTest, RequestFailedWhenRead) { + Initialize(kHttpUrl, 10, 29); + Start(); + PartialResponse(10, 29, 30); + + uint8 buffer[10]; + InSequence s; + + ReadLoader(10, 10, buffer); + EXPECT_CALL(*this, ReadCallback(net::ERR_FAILED)); + EXPECT_CALL(*this, NetworkCallback()); + WebURLError error; + error.reason = net::ERR_FAILED; + loader_->didFail(url_loader_, error); +} + +// Tests the logic of caching data to disk when media is paused. +TEST_F(BufferedResourceLoaderTest, AllowDefer_NoDataReceived) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + // Start in undeferred state, then disallow defer, then allow defer + // without receiving data in between. + DisallowLoaderDefer(); + AllowLoaderDefer(); + StopWhenLoad(); +} + +TEST_F(BufferedResourceLoaderTest, AllowDefer_ReadSameWindow) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + uint8 buffer[10]; + + // Start in undeferred state, disallow defer, receive data but don't shift + // buffer window, then allow defer and read. + DisallowLoaderDefer(); + WriteLoader(10, 10); + AllowLoaderDefer(); + + EXPECT_CALL(*this, ReadCallback(10)); + ReadLoader(10, 10, buffer); + VerifyBuffer(buffer, 10, 10); + StopWhenLoad(); +} + +TEST_F(BufferedResourceLoaderTest, AllowDefer_ReadPastWindow) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + uint8 buffer[10]; + + // Not deferred, disallow defer, received data and shift buffer window, + // allow defer, then read in area outside of buffer window. + DisallowLoaderDefer(); + WriteLoader(10, 10); + WriteLoader(20, 50); + AllowLoaderDefer(); + + EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); + ReadLoader(10, 10, buffer); + StopWhenLoad(); +} + +TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredNoDataReceived) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + uint8 buffer[10]; + + // Start in deferred state, then disallow defer, receive no data, and + // allow defer and read. + EXPECT_CALL(*url_loader_, setDefersLoading(true)); + EXPECT_CALL(*this, NetworkCallback()); + WriteLoader(10, 40); + + DisallowLoaderDefer(); + AllowLoaderDefer(); + + EXPECT_CALL(*this, ReadCallback(10)); + ReadLoader(20, 10, buffer); + VerifyBuffer(buffer, 20, 10); + StopWhenLoad(); +} + +TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredReadSameWindow) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + uint8 buffer[10]; + + // Start in deferred state, disallow defer, receive data and shift buffer + // window, allow defer, and read in a place that's still in the window. + EXPECT_CALL(*url_loader_, setDefersLoading(true)); + EXPECT_CALL(*this, NetworkCallback()); + WriteLoader(10, 30); + + DisallowLoaderDefer(); + WriteLoader(40, 5); + AllowLoaderDefer(); + + EXPECT_CALL(*this, ReadCallback(10)); + ReadLoader(20, 10, buffer); + VerifyBuffer(buffer, 20, 10); + StopWhenLoad(); +} + +TEST_F(BufferedResourceLoaderTest, AllowDefer_DeferredReadPastWindow) { + Initialize(kHttpUrl, 10, 99); + SetLoaderBuffer(10, 20); + Start(); + PartialResponse(10, 99, 100); + + uint8 buffer[10]; + + // Start in deferred state, disallow defer, receive data and shift buffer + // window, allow defer, and read outside of the buffer window. + EXPECT_CALL(*url_loader_, setDefersLoading(true)); + EXPECT_CALL(*this, NetworkCallback()); + WriteLoader(10, 40); + + DisallowLoaderDefer(); + WriteLoader(50, 20); + WriteLoader(70, 40); + AllowLoaderDefer(); + + EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS)); + ReadLoader(20, 5, buffer); + StopWhenLoad(); +} +// TODO(hclam): add unit test for defer loading. + +} // namespace webkit_glue + diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.cc b/webkit/glue/media/media_resource_loader_bridge_factory.cc deleted file mode 100644 index 3fb9d65..0000000 --- a/webkit/glue/media/media_resource_loader_bridge_factory.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/media/media_resource_loader_bridge_factory.h" - -#include "base/format_macros.h" -#include "base/string_util.h" -#include "base/stringprintf.h" - -namespace { - -// A constant for an unknown position. -const int64 kPositionNotSpecified = -1; - -} // namespace - -namespace webkit_glue { - -MediaResourceLoaderBridgeFactory::MediaResourceLoaderBridgeFactory( - const GURL& referrer, - const std::string& frame_origin, - const std::string& main_frame_origin, - int origin_pid, - int appcache_host_id, - int32 routing_id) - : referrer_(referrer), - frame_origin_(frame_origin), - main_frame_origin_(main_frame_origin), - origin_pid_(origin_pid), - appcache_host_id_(appcache_host_id), - routing_id_(routing_id) { -} - -MediaResourceLoaderBridgeFactory::~MediaResourceLoaderBridgeFactory() {} - -ResourceLoaderBridge* MediaResourceLoaderBridgeFactory::CreateBridge( - const GURL& url, - int load_flags, - int64 first_byte_position, - int64 last_byte_position) { - webkit_glue::ResourceLoaderBridge::RequestInfo request_info; - request_info.method = "GET"; - request_info.url = url; - request_info.first_party_for_cookies = url; - request_info.referrer = referrer_; - request_info.frame_origin = frame_origin_; - request_info.main_frame_origin = main_frame_origin_; - request_info.headers = GenerateHeaders(first_byte_position, - last_byte_position); - request_info.load_flags = load_flags; - request_info.requestor_pid = origin_pid_; - request_info.request_type = ResourceType::MEDIA; - request_info.appcache_host_id = appcache_host_id_; - request_info.routing_id = routing_id_; - return webkit_glue::ResourceLoaderBridge::Create(request_info); -} - -MediaResourceLoaderBridgeFactory::MediaResourceLoaderBridgeFactory() {} - -// static -const std::string MediaResourceLoaderBridgeFactory::GenerateHeaders ( - int64 first_byte_position, int64 last_byte_position) { - // Construct the range header. - std::string header; - if (first_byte_position > kPositionNotSpecified && - last_byte_position > kPositionNotSpecified) { - if (first_byte_position <= last_byte_position) { - header = base::StringPrintf("Range: bytes=%" PRId64 "-%" PRId64, - first_byte_position, - last_byte_position); - } - } else if (first_byte_position > kPositionNotSpecified) { - header = base::StringPrintf("Range: bytes=%" PRId64 "-", - first_byte_position); - } else if (last_byte_position > kPositionNotSpecified) { - NOTIMPLEMENTED() << "Suffix range not implemented"; - } - return header; -} - -} // namespace webkit_glue diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.h b/webkit/glue/media/media_resource_loader_bridge_factory.h deleted file mode 100644 index ccacdc6..0000000 --- a/webkit/glue/media/media_resource_loader_bridge_factory.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_MEDIA_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ -#define WEBKIT_GLUE_MEDIA_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ - -#include "base/gtest_prod_util.h" -#include "webkit/glue/resource_loader_bridge.h" - -namespace webkit_glue { - -// A factory used to create a ResourceLoaderBridge for the media player. -// This factory is used also for testing. Testing code can use this class and -// override CreateBridge() to inject a mock ResourceLoaderBridge for code that -// interacts with it, e.g. BufferedDataSource. -class MediaResourceLoaderBridgeFactory { - public: - MediaResourceLoaderBridgeFactory( - const GURL& referrer, - const std::string& frame_origin, - const std::string& main_frame_origin, - int origin_pid, - int appcache_host_id, - int32 routing_id); - - virtual ~MediaResourceLoaderBridgeFactory(); - - // Factory method to create a ResourceLoaderBridge with the following - // parameters: - // |url| - URL of the resource to be loaded. - // |load_flags| - Load flags for this loading. - // |first_byte_position| - First byte position for a range request, -1 if not. - // |last_byte_position| - Last byte position for a range request, -1 if not. - virtual ResourceLoaderBridge* CreateBridge( - const GURL& url, - int load_flags, - int64 first_byte_position, - int64 last_byte_position); - - protected: - // An empty constructor only used by inherited classes. - MediaResourceLoaderBridgeFactory(); - - private: - FRIEND_TEST_ALL_PREFIXES(MediaResourceLoaderBridgeFactoryTest, - GenerateHeaders); - - // Returns a range request header using parameters |first_byte_position| and - // |last_byte_position|. - // Negative numbers other than -1 are not allowed for |first_byte_position| - // and |last_byte_position|. |first_byte_position| should always be less than - // or equal to |last_byte_position| if they are both not -1. - // Here's a list of valid parameters: - // |first_byte_position| |last_byte_position| - // 0 1000 - // 4096 4096 - // 0 -1 - // -1 -1 - // Empty string is returned on invalid parameters. - static const std::string GenerateHeaders(int64 first_byte_position, - int64 last_byte_position); - - GURL first_party_for_cookies_; - GURL referrer_; - std::string frame_origin_; - std::string main_frame_origin_; - std::string headers_; - int origin_pid_; - int appcache_host_id_; - int32 routing_id_; -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_MEDIA_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ diff --git a/webkit/glue/media/media_resource_loader_bridge_factory_unittest.cc b/webkit/glue/media/media_resource_loader_bridge_factory_unittest.cc deleted file mode 100644 index 4c0126b..0000000 --- a/webkit/glue/media/media_resource_loader_bridge_factory_unittest.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/http/http_util.h" -#include "webkit/glue/media/media_resource_loader_bridge_factory.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace webkit_glue { - -TEST(MediaResourceLoaderBridgeFactoryTest, GenerateHeaders) { - static const struct { - const bool success; - const int64 first_byte_position; - const int64 last_byte_position; - } data[] = { - { false, -1, -1 }, - { false, -5, 0 }, - { false, 100, 0 }, - { true, 0, -1 }, - { true, 0, 0 }, - { true, 100, 100 }, - { true, 50, -1 }, - { true, 10000, -1 }, - { true, 50, 100 }, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { - std::string headers = MediaResourceLoaderBridgeFactory::GenerateHeaders( - data[i].first_byte_position, data[i].last_byte_position); - std::vector ranges; - bool ret = net::HttpUtil::ParseRanges(headers, &ranges); - EXPECT_EQ(data[i].success, ret); - if (ret) { - EXPECT_EQ(1u, ranges.size()); - EXPECT_EQ(data[i].first_byte_position, - ranges[0].first_byte_position()); - EXPECT_EQ(data[i].last_byte_position, - ranges[0].last_byte_position()); - } - } -} - -} // namespace webkit_glue diff --git a/webkit/glue/media/mock_media_resource_loader_bridge_factory.h b/webkit/glue/media/mock_media_resource_loader_bridge_factory.h deleted file mode 100644 index 3c0a3ae..0000000 --- a/webkit/glue/media/mock_media_resource_loader_bridge_factory.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ -#define WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ - -#include "testing/gmock/include/gmock/gmock.h" -#include "webkit/glue/media/media_resource_loader_bridge_factory.h" - -namespace webkit_glue { - -class MockMediaResourceLoaderBridgeFactory - : public webkit_glue::MediaResourceLoaderBridgeFactory { - public: - MockMediaResourceLoaderBridgeFactory() { - } - - virtual ~MockMediaResourceLoaderBridgeFactory() { - OnDestroy(); - } - - MOCK_METHOD4(CreateBridge, - webkit_glue::ResourceLoaderBridge*(const GURL& url, - int load_flags, - int64 first_byte_position, - int64 last_byte_position)); - MOCK_METHOD0(OnDestroy, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockMediaResourceLoaderBridgeFactory); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_MEDIA_MOCK_MEDIA_RESOURCE_LOADER_BRIDGE_FACTORY_H_ diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc index 291928e..8869e28 100644 --- a/webkit/glue/media/simple_data_source.cc +++ b/webkit/glue/media/simple_data_source.cc @@ -2,40 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "webkit/glue/media/simple_data_source.h" + #include "base/message_loop.h" #include "base/process_util.h" #include "media/base/filter_host.h" -#include "net/base/load_flags.h" #include "net/base/data_url.h" -#include "net/http/http_response_headers.h" +#include "net/base/load_flags.h" #include "net/url_request/url_request_status.h" -#include "webkit/glue/media/simple_data_source.h" -#include "webkit/glue/resource_loader_bridge.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" #include "webkit/glue/webkit_glue.h" namespace { -const char kHttpScheme[] = "http"; -const char kHttpsScheme[] = "https"; const char kDataScheme[] = "data"; -// A helper method that accepts only HTTP, HTTPS and FILE protocol. -bool IsDataProtocol(const GURL& url) { - return url.SchemeIs(kDataScheme); -} - } // namespace namespace webkit_glue { SimpleDataSource::SimpleDataSource( MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) + WebKit::WebFrame* frame) : render_loop_(render_loop), - bridge_factory_(bridge_factory), + frame_(frame), size_(-1), single_origin_(true), - state_(UNINITIALIZED) { + state_(UNINITIALIZED), + keep_test_loader_(false) { DCHECK(render_loop); } @@ -108,34 +103,59 @@ bool SimpleDataSource::IsStreaming() { return false; } -bool SimpleDataSource::OnReceivedRedirect( - const GURL& new_url, - const webkit_glue::ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies) { +void SimpleDataSource::SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader) { + url_loader_.reset(mock_loader); + keep_test_loader_ = true; +} + +void SimpleDataSource::willSendRequest( + WebKit::WebURLLoader* loader, + WebKit::WebURLRequest& newRequest, + const WebKit::WebURLResponse& redirectResponse) { DCHECK(MessageLoop::current() == render_loop_); - single_origin_ = url_.GetOrigin() == new_url.GetOrigin(); + single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); - // TODO(wtc): should we return a new first party for cookies URL? - *has_new_first_party_for_cookies = false; - return true; + url_ = newRequest.url(); } -void SimpleDataSource::OnReceivedResponse( - const webkit_glue::ResourceResponseInfo& info, - bool content_filtered) { +void SimpleDataSource::didSendData( + WebKit::WebURLLoader* loader, + unsigned long long bytesSent, + unsigned long long totalBytesToBeSent) { + NOTIMPLEMENTED(); +} + +void SimpleDataSource::didReceiveResponse( + WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response) { DCHECK(MessageLoop::current() == render_loop_); - size_ = info.content_length; + size_ = response.expectedContentLength(); +} + +void SimpleDataSource::didDownloadData( + WebKit::WebURLLoader* loader, + int dataLength) { + NOTIMPLEMENTED(); } -void SimpleDataSource::OnReceivedData(const char* data, int len) { +void SimpleDataSource::didReceiveData( + WebKit::WebURLLoader* loader, + const char* data, + int data_length) { DCHECK(MessageLoop::current() == render_loop_); - data_.append(data, len); + data_.append(data, data_length); } -void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info, - const base::Time& completion_time) { +void SimpleDataSource::didReceiveCachedMetadata( + WebKit::WebURLLoader* loader, + const char* data, + int dataLength) { + NOTIMPLEMENTED(); +} + +void SimpleDataSource::didFinishLoading( + WebKit::WebURLLoader* loader, + double finishTime) { DCHECK(MessageLoop::current() == render_loop_); AutoLock auto_lock(lock_); // It's possible this gets called after Stop(), in which case |host_| is no @@ -143,10 +163,8 @@ void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, if (state_ == STOPPED) return; - // Otherwise we should be initializing and have created a bridge. + // Otherwise we should be initializing and have created a WebURLLoader. DCHECK_EQ(state_, INITIALIZING); - DCHECK(bridge_.get()); - bridge_.reset(); // If we don't get a content length or the request has failed, report it // as a network error. @@ -154,7 +172,29 @@ void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, size_ = data_.length(); DCHECK(static_cast(size_) == data_.length()); - DoneInitialization_Locked(status.is_success()); + DoneInitialization_Locked(true); +} + +void SimpleDataSource::didFail( + WebKit::WebURLLoader* loader, + const WebKit::WebURLError& error) { + DCHECK(MessageLoop::current() == render_loop_); + AutoLock auto_lock(lock_); + // It's possible this gets called after Stop(), in which case |host_| is no + // longer valid. + if (state_ == STOPPED) + return; + + // Otherwise we should be initializing and have created a WebURLLoader. + DCHECK_EQ(state_, INITIALIZING); + + // If we don't get a content length or the request has failed, report it + // as a network error. + if (size_ == -1) + size_ = data_.length(); + DCHECK(static_cast(size_) == data_.length()); + + DoneInitialization_Locked(false); } bool SimpleDataSource::HasSingleOrigin() { @@ -164,7 +204,7 @@ bool SimpleDataSource::HasSingleOrigin() { void SimpleDataSource::Abort() { DCHECK(MessageLoop::current() == render_loop_); - NOTIMPLEMENTED(); + frame_ = NULL; } void SimpleDataSource::SetURL(const GURL& url) { @@ -183,9 +223,11 @@ void SimpleDataSource::StartTask() { if (state_ == STOPPED) return; + CHECK(frame_); + DCHECK_EQ(state_, INITIALIZING); - if (IsDataProtocol(url_)) { + if (url_.SchemeIs(kDataScheme)) { // If this using data protocol, we just need to decode it. std::string mime_type, charset; bool success = net::DataURL::Parse(url_, &mime_type, &charset, &data_); @@ -194,10 +236,18 @@ void SimpleDataSource::StartTask() { size_ = data_.length(); DoneInitialization_Locked(success); } else { - // Create our bridge and start loading the resource. - bridge_.reset(bridge_factory_->CreateBridge( - url_, net::LOAD_BYPASS_CACHE, -1, -1)); - bridge_->Start(this); + // Prepare the request. + WebKit::WebURLRequest request(url_); + request.setTargetType(WebKit::WebURLRequest::TargetIsMedia); + + frame_->setReferrerForRequest(request, WebKit::WebURL()); + + // This flag is for unittests as we don't want to reset |url_loader| + if (!keep_test_loader_) + url_loader_.reset(frame_->createAssociatedURLLoader()); + + // Start the resource loading. + url_loader_->loadAsynchronously(request, this); } } @@ -207,9 +257,9 @@ void SimpleDataSource::CancelTask() { DCHECK_EQ(state_, STOPPED); // Cancel any pending requests. - if (bridge_.get()) { - bridge_->Cancel(); - bridge_.reset(); + if (url_loader_.get()) { + url_loader_->cancel(); + url_loader_.reset(); } } @@ -220,7 +270,7 @@ void SimpleDataSource::DoneInitialization_Locked(bool success) { host()->SetTotalBytes(size_); host()->SetBufferedBytes(size_); // If scheme is file or data, say we are loaded. - host()->SetLoaded(url_.SchemeIsFile() || IsDataProtocol(url_)); + host()->SetLoaded(url_.SchemeIsFile() || url_.SchemeIs(kDataScheme)); } else { host()->SetError(media::PIPELINE_ERROR_NETWORK); } diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h index ff1e247..f4c83e6 100644 --- a/webkit/glue/media/simple_data_source.h +++ b/webkit/glue/media/simple_data_source.h @@ -10,10 +10,17 @@ #ifndef WEBKIT_GLUE_MEDIA_SIMPLE_DATA_SOURCE_H_ #define WEBKIT_GLUE_MEDIA_SIMPLE_DATA_SOURCE_H_ +#include +#include + #include "base/message_loop.h" #include "base/scoped_ptr.h" #include "media/base/filters.h" -#include "webkit/glue/media/media_resource_loader_bridge_factory.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/glue/media/web_data_source.h" class MessageLoop; @@ -22,17 +29,15 @@ class WebMediaPlayerDelegateImpl; namespace webkit_glue { class SimpleDataSource : public WebDataSource, - public webkit_glue::ResourceLoaderBridge::Peer { + public WebKit::WebURLLoaderClient { public: - SimpleDataSource( - MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); + SimpleDataSource(MessageLoop* render_loop, WebKit::WebFrame* frame); virtual ~SimpleDataSource(); - // MediaFilter implementation. + // media::Filter implementation. virtual void Stop(media::FilterCallback* callback); - // DataSource implementation. + // media::DataSource implementation. virtual void Initialize(const std::string& url, media::FilterCallback* callback); virtual const media::MediaFormat& media_format(); @@ -41,21 +46,37 @@ class SimpleDataSource : public WebDataSource, virtual bool GetSize(int64* size_out); virtual bool IsStreaming(); - // webkit_glue::ResourceLoaderBridge::Peer implementation. - virtual void OnUploadProgress(uint64 position, uint64 size) {} - virtual bool OnReceivedRedirect( - const GURL& new_url, - const webkit_glue::ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies); - virtual void OnReceivedResponse( - const webkit_glue::ResourceResponseInfo& info, - bool content_filtered); - virtual void OnDownloadedData(int len) {} - virtual void OnReceivedData(const char* data, int len); - virtual void OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info, - const base::Time& completion_time); + // Used to inject a mock used for unittests. + virtual void SetURLLoaderForTest(WebKit::WebURLLoader* mock_loader); + + // WebKit::WebURLLoaderClient implementations. + virtual void willSendRequest( + WebKit::WebURLLoader* loader, + WebKit::WebURLRequest& newRequest, + const WebKit::WebURLResponse& redirectResponse); + virtual void didSendData( + WebKit::WebURLLoader* loader, + unsigned long long bytesSent, + unsigned long long totalBytesToBeSent); + virtual void didReceiveResponse( + WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response); + virtual void didDownloadData( + WebKit::WebURLLoader* loader, + int dataLength); + virtual void didReceiveData( + WebKit::WebURLLoader* loader, + const char* data, + int dataLength); + virtual void didReceiveCachedMetadata( + WebKit::WebURLLoader* loader, + const char* data, int dataLength); + virtual void didFinishLoading( + WebKit::WebURLLoader* loader, + double finishTime); + virtual void didFail( + WebKit::WebURLLoader* loader, + const WebKit::WebURLError&); // webkit_glue::WebDataSource implementation. virtual bool HasSingleOrigin(); @@ -77,11 +98,11 @@ class SimpleDataSource : public WebDataSource, // Primarily used for asserting the bridge is loading on the render thread. MessageLoop* render_loop_; - // Factory to create a bridge. - scoped_ptr bridge_factory_; + // A webframe for loading. + WebKit::WebFrame* frame_; - // Bridge used to load the media resource. - scoped_ptr bridge_; + // Does the work of loading and sends data back to this client. + scoped_ptr url_loader_; media::MediaFormat media_format_; GURL url_; @@ -104,6 +125,9 @@ class SimpleDataSource : public WebDataSource, // Filter callbacks. scoped_ptr initialize_callback_; + // Used to ensure mocks for unittests are used instead of reset in Start(). + bool keep_test_loader_; + DISALLOW_COPY_AND_ASSIGN(SimpleDataSource); }; diff --git a/webkit/glue/media/simple_data_source_unittest.cc b/webkit/glue/media/simple_data_source_unittest.cc index 537798f..55dc913 100644 --- a/webkit/glue/media/simple_data_source_unittest.cc +++ b/webkit/glue/media/simple_data_source_unittest.cc @@ -6,9 +6,15 @@ #include "media/base/filters.h" #include "media/base/mock_filter_host.h" #include "media/base/mock_filters.h" -#include "webkit/glue/media/mock_media_resource_loader_bridge_factory.h" +#include "net/base/net_errors.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/glue/media/simple_data_source.h" -#include "webkit/glue/mock_resource_loader_bridge.h" +#include "webkit/mocks/mock_webframe.h" +#include "webkit/mocks/mock_weburlloader.h" using ::testing::_; using ::testing::DoAll; @@ -21,6 +27,11 @@ using ::testing::SetArgumentPointee; using ::testing::StrictMock; using ::testing::WithArgs; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; + namespace { const int kDataSize = 1024; @@ -39,68 +50,56 @@ namespace webkit_glue { class SimpleDataSourceTest : public testing::Test { public: SimpleDataSourceTest() { - bridge_factory_.reset( - new NiceMock()); - bridge_.reset(new NiceMock()); - for (int i = 0; i < kDataSize; ++i) { data_[i] = i; } } virtual ~SimpleDataSourceTest() { - if (bridge_.get()) - EXPECT_CALL(*bridge_, OnDestroy()); - if (bridge_factory_.get()) - EXPECT_CALL(*bridge_factory_, OnDestroy()); + ignore_result(frame_.release()); } void InitializeDataSource(const char* url) { + gurl_ = GURL(url); + + frame_.reset(new NiceMock()); + url_loader_ = new NiceMock(); + data_source_ = new SimpleDataSource(MessageLoop::current(), - bridge_factory_.get()); - CHECK(data_source_); + frame_.get()); // There is no need to provide a message loop to data source. data_source_->set_host(&host_); + data_source_->SetURLLoaderForTest(url_loader_); - // First a bridge is created. InSequence s; - EXPECT_CALL(*bridge_factory_, CreateBridge(GURL(url), _, -1, -1)) - .WillOnce(Return(bridge_.get())); - EXPECT_CALL(*bridge_, Start(data_source_.get())) - .WillOnce(Return(true)); data_source_->Initialize(url, callback_.NewCallback()); - MessageLoop::current()->RunAllPending(); } void RequestSucceeded(bool is_loaded) { - ResourceResponseInfo info; - info.content_length = kDataSize; + WebURLResponse response(gurl_); + response.setExpectedContentLength(kDataSize); - data_source_->OnReceivedResponse(info, false); + data_source_->didReceiveResponse(NULL, response); int64 size; EXPECT_TRUE(data_source_->GetSize(&size)); EXPECT_EQ(kDataSize, size); - for (int i = 0; i < kDataSize; ++i) - data_source_->OnReceivedData(data_ + i, 1); + for (int i = 0; i < kDataSize; ++i) { + data_source_->didReceiveData(NULL, data_ + i, 1); + } EXPECT_CALL(host_, SetLoaded(is_loaded)); InSequence s; - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &SimpleDataSourceTest::ReleaseBridge)); EXPECT_CALL(host_, SetTotalBytes(kDataSize)); EXPECT_CALL(host_, SetBufferedBytes(kDataSize)); EXPECT_CALL(callback_, OnFilterCallback()); EXPECT_CALL(callback_, OnCallbackDestroyed()); - URLRequestStatus status; - status.set_status(URLRequestStatus::SUCCESS); - status.set_os_error(0); - data_source_->OnCompletedRequest(status, "", base::Time()); + data_source_->didFinishLoading(NULL, 0); // Let the tasks to be executed. MessageLoop::current()->RunAllPending(); @@ -108,28 +107,23 @@ class SimpleDataSourceTest : public testing::Test { void RequestFailed() { InSequence s; - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &SimpleDataSourceTest::ReleaseBridge)); EXPECT_CALL(host_, SetError(media::PIPELINE_ERROR_NETWORK)); EXPECT_CALL(callback_, OnFilterCallback()); EXPECT_CALL(callback_, OnCallbackDestroyed()); - URLRequestStatus status; - status.set_status(URLRequestStatus::FAILED); - status.set_os_error(100); - data_source_->OnCompletedRequest(status, "", base::Time()); + WebURLError error; + error.reason = net::ERR_FAILED; + data_source_->didFail(NULL, error); // Let the tasks to be executed. MessageLoop::current()->RunAllPending(); } void DestroyDataSource() { - EXPECT_CALL(*bridge_factory_, OnDestroy()) - .WillOnce(Invoke(this, &SimpleDataSourceTest::ReleaseBridgeFactory)); - StrictMock callback; EXPECT_CALL(callback, OnFilterCallback()); EXPECT_CALL(callback, OnCallbackDestroyed()); + data_source_->Stop(callback.NewCallback()); MessageLoop::current()->RunAllPending(); @@ -148,23 +142,17 @@ class SimpleDataSourceTest : public testing::Test { } } - void ReleaseBridge() { - ignore_result(bridge_.release()); - } - - void ReleaseBridgeFactory() { - ignore_result(bridge_factory_.release()); - } - MOCK_METHOD1(ReadCallback, void(size_t size)); protected: + GURL gurl_; scoped_ptr message_loop_; - scoped_ptr > bridge_factory_; - scoped_ptr > bridge_; + NiceMock* url_loader_; scoped_refptr data_source_; StrictMock host_; StrictMock callback_; + scoped_ptr > frame_; + char data_[kDataSize]; DISALLOW_COPY_AND_ASSIGN(SimpleDataSourceTest); @@ -189,13 +177,16 @@ TEST_F(SimpleDataSourceTest, InitializeFile) { } TEST_F(SimpleDataSourceTest, InitializeData) { + frame_.reset(new NiceMock()); + url_loader_ = new NiceMock(); + data_source_ = new SimpleDataSource(MessageLoop::current(), - bridge_factory_.get()); + frame_.get()); EXPECT_TRUE(data_source_->IsUrlSupported(kDataUrl)); - CHECK(data_source_); // There is no need to provide a message loop to data source. data_source_->set_host(&host_); + data_source_->SetURLLoaderForTest(url_loader_); EXPECT_CALL(host_, SetLoaded(true)); EXPECT_CALL(host_, SetTotalBytes(sizeof(kDataUrlDecoded))); @@ -218,9 +209,7 @@ TEST_F(SimpleDataSourceTest, RequestFailed) { TEST_F(SimpleDataSourceTest, StopWhenDownloading) { InitializeDataSource(kHttpUrl); - EXPECT_CALL(*bridge_, Cancel()); - EXPECT_CALL(*bridge_, OnDestroy()) - .WillOnce(Invoke(this, &SimpleDataSourceTest::ReleaseBridge)); + EXPECT_CALL(*url_loader_, cancel()); EXPECT_CALL(callback_, OnCallbackDestroyed()); DestroyDataSource(); } diff --git a/webkit/glue/mimetype_unittest.cc b/webkit/glue/mimetype_unittest.cc index 1c2e5f4..3f17e79 100644 --- a/webkit/glue/mimetype_unittest.cc +++ b/webkit/glue/mimetype_unittest.cc @@ -23,12 +23,12 @@ class MimeTypeTests : public TestShellTest { test_shell_->WaitTestFinished(); } - void CheckMimeType(const char* mimetype, const std::wstring& expected) { + void CheckMimeType(const char* mimetype, const std::string& expected) { std::string path("contenttype?"); GURL url(test_server_.GetURL(path + mimetype)); LoadURL(url); WebFrame* frame = test_shell_->webView()->mainFrame(); - EXPECT_EQ(expected, webkit_glue::DumpDocumentText(frame)); + EXPECT_EQ(expected, UTF16ToASCII(webkit_glue::DumpDocumentText(frame))); } UnittestTestServer test_server_; @@ -37,8 +37,8 @@ class MimeTypeTests : public TestShellTest { TEST_F(MimeTypeTests, MimeTypeTests) { ASSERT_TRUE(test_server_.Start()); - std::wstring expected_src(L"\n\n" - L"

HTML text

\n\n\n"); + std::string expected_src("\n\n" + "

HTML text

\n\n\n"); // These files should all be displayed as plain text. const char* plain_text[] = { @@ -66,7 +66,7 @@ TEST_F(MimeTypeTests, MimeTypeTests) { "application/xhtml+xml", }; for (size_t i = 0; i < arraysize(html_src); ++i) { - CheckMimeType(html_src[i], L"HTML text"); + CheckMimeType(html_src[i], "HTML text"); } // These shouldn't be rendered as text or HTML, but shouldn't download @@ -78,7 +78,7 @@ TEST_F(MimeTypeTests, MimeTypeTests) { "image/bmp", }; for (size_t i = 0; i < arraysize(not_text); ++i) { - CheckMimeType(not_text[i], L""); + CheckMimeType(not_text[i], ""); test_shell_->webView()->mainFrame()->stopLoading(); } diff --git a/webkit/glue/mock_resource_loader_bridge.h b/webkit/glue/mock_resource_loader_bridge.h deleted file mode 100644 index 49c41ed..0000000 --- a/webkit/glue/mock_resource_loader_bridge.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ -#define WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ - -#include "testing/gmock/include/gmock/gmock.h" -#include "webkit/glue/resource_loader_bridge.h" - -class FilePath; - -namespace webkit_glue { - -class MockResourceLoaderBridge : public webkit_glue::ResourceLoaderBridge { - public: - MockResourceLoaderBridge() { - } - - virtual ~MockResourceLoaderBridge() { - OnDestroy(); - } - - MOCK_METHOD2(AppendDataToUpload, void(const char* data, int data_len)); - MOCK_METHOD4(AppendFileRangeToUpload, - void(const FilePath& file_path, - uint64 offset, - uint64 length, - const base::Time& expected_modification_time)); - MOCK_METHOD1(AppendBlobToUpload, void(const GURL& blob_url)); - MOCK_METHOD1(SetUploadIdentifier, void(int64 identifier)); - MOCK_METHOD1(Start, bool(ResourceLoaderBridge::Peer* peer)); - MOCK_METHOD0(Cancel, void()); - MOCK_METHOD1(SetDefersLoading, void(bool value)); - MOCK_METHOD1(SyncLoad, void(SyncLoadResponse* response)); - MOCK_METHOD0(OnDestroy, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockResourceLoaderBridge); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_MOCK_RESOURCE_LOADER_BRIDGE_H_ diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc index 99a9e4c..b8c7758 100644 --- a/webkit/glue/multipart_response_delegate.cc +++ b/webkit/glue/multipart_response_delegate.cc @@ -316,7 +316,8 @@ bool MultipartResponseDelegate::ReadMultipartBoundary( bool MultipartResponseDelegate::ReadContentRanges( const WebURLResponse& response, int* content_range_lower_bound, - int* content_range_upper_bound) { + int* content_range_upper_bound, + int* content_range_instance_size) { std::string content_range = response.httpHeaderField("Content-Range").utf8(); if (content_range.empty()) { @@ -336,12 +337,20 @@ bool MultipartResponseDelegate::ReadContentRanges( // Skip over the initial space. byte_range_lower_bound_start_offset++; + // Find the lower bound. size_t byte_range_lower_bound_end_offset = content_range.find("-", byte_range_lower_bound_start_offset); if (byte_range_lower_bound_end_offset == std::string::npos) { return false; } + size_t byte_range_lower_bound_characters = + byte_range_lower_bound_end_offset - byte_range_lower_bound_start_offset; + std::string byte_range_lower_bound = + content_range.substr(byte_range_lower_bound_start_offset, + byte_range_lower_bound_characters); + + // Find the upper bound. size_t byte_range_upper_bound_start_offset = byte_range_lower_bound_end_offset + 1; @@ -351,16 +360,31 @@ bool MultipartResponseDelegate::ReadContentRanges( return false; } - if (!base::StringToInt( - content_range.begin() + byte_range_lower_bound_start_offset, - content_range.begin() + byte_range_lower_bound_end_offset, - content_range_lower_bound)) - return false; + size_t byte_range_upper_bound_characters = + byte_range_upper_bound_end_offset - byte_range_upper_bound_start_offset; + std::string byte_range_upper_bound = + content_range.substr(byte_range_upper_bound_start_offset, + byte_range_upper_bound_characters); + + // Find the instance size. + size_t byte_range_instance_size_start_offset = + byte_range_upper_bound_end_offset + 1; + + size_t byte_range_instance_size_end_offset = + content_range.length(); - if (!base::StringToInt( - content_range.begin() + byte_range_upper_bound_start_offset, - content_range.begin() + byte_range_upper_bound_end_offset, - content_range_upper_bound)) + size_t byte_range_instance_size_characters = + byte_range_instance_size_end_offset - + byte_range_instance_size_start_offset; + std::string byte_range_instance_size = + content_range.substr(byte_range_instance_size_start_offset, + byte_range_instance_size_characters); + + if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) + return false; + if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) + return false; + if (!base::StringToInt(byte_range_instance_size, content_range_instance_size)) return false; return true; } diff --git a/webkit/glue/multipart_response_delegate.h b/webkit/glue/multipart_response_delegate.h index aded54a..0500983 100644 --- a/webkit/glue/multipart_response_delegate.h +++ b/webkit/glue/multipart_response_delegate.h @@ -92,7 +92,8 @@ class MultipartResponseDelegate { // Returns true on success. static bool ReadContentRanges(const WebKit::WebURLResponse& response, int* content_range_lower_bound, - int* content_range_upper_bound); + int* content_range_upper_bound, + int* content_range_instance_size); private: friend class MultipartResponseDelegateTester; // For unittests. diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc index fab798c..1837cb5 100644 --- a/webkit/glue/multipart_response_delegate_unittest.cc +++ b/webkit/glue/multipart_response_delegate_unittest.cc @@ -550,10 +550,12 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { int content_range_lower_bound = 0; int content_range_upper_bound = 0; + int content_range_instance_size = 0; bool result = MultipartResponseDelegate::ReadContentRanges( response1, &content_range_lower_bound, - &content_range_upper_bound); + &content_range_upper_bound, + &content_range_instance_size); EXPECT_EQ(result, true); EXPECT_EQ(content_range_lower_bound, 1000); @@ -567,10 +569,12 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { content_range_lower_bound = 0; content_range_upper_bound = 0; + content_range_instance_size = 0; result = MultipartResponseDelegate::ReadContentRanges( response2, &content_range_lower_bound, - &content_range_upper_bound); + &content_range_upper_bound, + &content_range_instance_size); EXPECT_EQ(result, false); @@ -582,10 +586,12 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { content_range_lower_bound = 0; content_range_upper_bound = 0; + content_range_instance_size = 0; result = MultipartResponseDelegate::ReadContentRanges( response3, &content_range_lower_bound, - &content_range_upper_bound); + &content_range_upper_bound, + &content_range_instance_size); EXPECT_EQ(result, true); EXPECT_EQ(content_range_lower_bound, 1000); @@ -598,10 +604,12 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { content_range_lower_bound = 0; content_range_upper_bound = 0; + content_range_instance_size = 0; result = MultipartResponseDelegate::ReadContentRanges( response4, &content_range_lower_bound, - &content_range_upper_bound); + &content_range_upper_bound, + &content_range_instance_size); EXPECT_EQ(result, false); } diff --git a/webkit/glue/plugins/DEPS b/webkit/glue/plugins/DEPS deleted file mode 100644 index cfee702..0000000 --- a/webkit/glue/plugins/DEPS +++ /dev/null @@ -1,4 +0,0 @@ -include_rules = [ - "+ppapi", - "+printing", -] diff --git a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc deleted file mode 100644 index c4ae72d..0000000 --- a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/logging.h" -#include "webkit/glue/plugins/carbon_plugin_window_tracker_mac.h" - -CarbonPluginWindowTracker::CarbonPluginWindowTracker() { -} - -CarbonPluginWindowTracker* CarbonPluginWindowTracker::SharedInstance() { - static CarbonPluginWindowTracker* tracker = new CarbonPluginWindowTracker(); - return tracker; -} - -WindowRef CarbonPluginWindowTracker::CreateDummyWindowForDelegate( - OpaquePluginRef delegate) { - // The real size will be set by the plugin instance, once that size is known. - Rect window_bounds = { 0, 0, 100, 100 }; - WindowRef new_ref = NULL; - if (CreateNewWindow(kDocumentWindowClass, - kWindowNoTitleBarAttribute, - &window_bounds, - &new_ref) == noErr) { - window_to_delegate_map_[new_ref] = delegate; - delegate_to_window_map_[delegate] = new_ref; - } - return new_ref; -} - -OpaquePluginRef CarbonPluginWindowTracker::GetDelegateForDummyWindow( - WindowRef window) const { - WindowToDelegateMap::const_iterator i = window_to_delegate_map_.find(window); - if (i != window_to_delegate_map_.end()) - return i->second; - return NULL; -} - -WindowRef CarbonPluginWindowTracker::GetDummyWindowForDelegate( - OpaquePluginRef delegate) const { - DelegateToWindowMap::const_iterator i = - delegate_to_window_map_.find(delegate); - if (i != delegate_to_window_map_.end()) - return i->second; - return NULL; -} - -void CarbonPluginWindowTracker::DestroyDummyWindowForDelegate( - OpaquePluginRef delegate, WindowRef window) { - DCHECK(GetDelegateForDummyWindow(window) == delegate); - window_to_delegate_map_.erase(window); - delegate_to_window_map_.erase(delegate); - if (window) // Check just in case the initial window creation failed. - DisposeWindow(window); -} diff --git a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h deleted file mode 100644 index 90fc318..0000000 --- a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_CARBON_PLUGIN_WINDOW_TRACKER_MAC_H_ -#define WEBKIT_GLUE_PLUGINS_CARBON_PLUGIN_WINDOW_TRACKER_MAC_H_ - -#include -#include - -#include "base/basictypes.h" - -// This is really a WebPluginDelegateImpl, but that class is private to the -// framework, and these functions are called from a dylib. -typedef void* OpaquePluginRef; - -// Creates and tracks the invisible windows that are necessary for -// Carbon-event-model plugins. -// -// Serves as a bridge between plugin delegate instances and the Carbon -// interposing library. The Carbon functions we interpose work in terms of -// WindowRefs, and we need to be able to map from those back to the plugin -// delegates that know what we should claim about the state of the window. -class __attribute__((visibility("default"))) CarbonPluginWindowTracker { - public: - CarbonPluginWindowTracker(); - - // Returns the shared window tracker instance. - static CarbonPluginWindowTracker* SharedInstance(); - - // Creates a new carbon window associated with |delegate|. - WindowRef CreateDummyWindowForDelegate(OpaquePluginRef delegate); - - // Returns the WebPluginDelegate associated with the given dummy window. - OpaquePluginRef GetDelegateForDummyWindow(WindowRef window) const; - - // Returns the dummy window associated with |delegate|. - WindowRef GetDummyWindowForDelegate(OpaquePluginRef delegate) const; - - // Destroys the dummy window for |delegate|. - void DestroyDummyWindowForDelegate(OpaquePluginRef delegate, - WindowRef window); - - private: - typedef std::map WindowToDelegateMap; - typedef std::map DelegateToWindowMap; - WindowToDelegateMap window_to_delegate_map_; - DelegateToWindowMap delegate_to_window_map_; - - DISALLOW_COPY_AND_ASSIGN(CarbonPluginWindowTracker); -}; - -#endif // WEBKIT_GLUE_PLUGINS_CARBON_PLUGIN_WINDOW_TRACKER_MAC_H_ diff --git a/webkit/glue/plugins/coregraphics_private_symbols_mac.h b/webkit/glue/plugins/coregraphics_private_symbols_mac.h deleted file mode 100644 index 0342d6f..0000000 --- a/webkit/glue/plugins/coregraphics_private_symbols_mac.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_COREGRAPHICS_PRIVATE_SYMBOLS_MAC_H_ -#define WEBKIT_GLUE_PLUGINS_COREGRAPHICS_PRIVATE_SYMBOLS_MAC_H_ - -// These are CoreGraphics SPI, verified to exist in both 10.5 and 10.6. - -#ifdef __cplusplus -extern "C" { -#endif - -// Copies the contents of the window with id |wid| into the given rect in the -// given context -OSStatus CGContextCopyWindowCaptureContentsToRect( - CGContextRef, CGRect, int cid, int wid, int unknown); - -// Returns the connection ID we need for the third argument to -// CGContextCopyWindowCaptureContentsToRect -int _CGSDefaultConnection(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // WEBKIT_GLUE_PLUGINS_COREGRAPHICS_PRIVATE_SYMBOLS_MAC_H_ diff --git a/webkit/glue/plugins/default_plugin_shared.h b/webkit/glue/plugins/default_plugin_shared.h deleted file mode 100644 index 79d06b3..0000000 --- a/webkit/glue/plugins/default_plugin_shared.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Thes file contains stuff that should be shared among projects that do some -// special handling with default plugin - -#ifndef WEBKIT_GLUE_PLUGINS_DEFAULT_PLUGIN_SHARED_H -#define WEBKIT_GLUE_PLUGINS_DEFAULT_PLUGIN_SHARED_H - -namespace default_plugin { - -// We use the NPNGetValue host function to send notification message to host. -// This corresponds to NPNVariable defined in npapi.h, and should be chosen so -// as to not overlap values if NPAPI is updated. - -const int kMissingPluginStatusStart = 5000; - -enum MissingPluginStatus { - MISSING_PLUGIN_AVAILABLE, - MISSING_PLUGIN_USER_STARTED_DOWNLOAD -}; - -#if defined(OS_WIN) -#include -const int kInstallMissingPluginMessage = WM_APP + 117; -#endif - -} // namespace default_plugin - -#endif // WEBKIT_GLUE_PLUGINS_DEFAULT_PLUGIN_SHARED_H diff --git a/webkit/glue/plugins/gtk_plugin_container.cc b/webkit/glue/plugins/gtk_plugin_container.cc deleted file mode 100644 index c80bbf1..0000000 --- a/webkit/glue/plugins/gtk_plugin_container.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/gtk_plugin_container.h" - -#include - -#include "base/basictypes.h" - -namespace { - -// NOTE: This class doesn't have constructors/destructors, it is created -// through GLib's object management. -class GtkPluginContainer : public GtkSocket { - public: - // Sets the requested size of the widget. - void set_size(int width, int height) { - width_ = width; - height_ = height; - } - - // Casts a widget into a GtkPluginContainer, after checking the type. - template - static GtkPluginContainer *CastChecked(T *instance) { - return G_TYPE_CHECK_INSTANCE_CAST(instance, GetType(), GtkPluginContainer); - } - - // Create and register our custom container type with GTK. - static GType GetType() { - static GType type = 0; // We only want to register our type once. - if (!type) { - static const GTypeInfo info = { - sizeof(GtkSocketClass), - NULL, NULL, - static_cast(&ClassInit), - NULL, NULL, - sizeof(GtkPluginContainer), - 0, &InstanceInit, - }; - type = g_type_register_static(GTK_TYPE_SOCKET, - "GtkPluginContainer", - &info, - static_cast(0)); - } - return type; - } - - // Implementation of the class initializer. - static void ClassInit(gpointer klass, gpointer class_data_unusued) { - GtkWidgetClass* widget_class = reinterpret_cast(klass); - widget_class->size_request = &HandleSizeRequest; - } - - // Implementation of the instance initializer (constructor). - static void InstanceInit(GTypeInstance *instance, gpointer klass) { - GtkPluginContainer *container = CastChecked(instance); - container->set_size(0, 0); - } - - // Report our allocation size during size requisition. - static void HandleSizeRequest(GtkWidget* widget, - GtkRequisition* requisition) { - GtkPluginContainer *container = CastChecked(widget); - requisition->width = container->width_; - requisition->height = container->height_; - } - - int width_; - int height_; - DISALLOW_IMPLICIT_CONSTRUCTORS(GtkPluginContainer); -}; - -} // anonymous namespace - -// Create a new instance of our GTK widget object. -GtkWidget* gtk_plugin_container_new() { - return GTK_WIDGET(g_object_new(GtkPluginContainer::GetType(), NULL)); -} - -void gtk_plugin_container_set_size(GtkWidget *widget, int width, int height) { - GtkPluginContainer::CastChecked(widget)->set_size(width, height); - // Signal the parent that the size request has changed. - gtk_widget_queue_resize_no_redraw(widget); -} diff --git a/webkit/glue/plugins/gtk_plugin_container.h b/webkit/glue/plugins/gtk_plugin_container.h deleted file mode 100644 index eed6b94..0000000 --- a/webkit/glue/plugins/gtk_plugin_container.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_H_ -#define WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_H_ - -// Windowed plugins are embedded via XEmbed, which is implemented by -// GtkPlug/GtkSocket. But we want to control sizing and positioning -// directly, so we need a subclass of GtkSocket that sidesteps the -// size_request handler. -// -// The custom size_request handler just reports the size set by -// gtk_plugin_container_set_size. - -typedef struct _GtkWidget GtkWidget; - -// Return a new GtkPluginContainer. -// Intentionally GTK-style here since we're creating a custom GTK widget. -// This is a GtkSocket subclass; see its documentation for available methods. -GtkWidget* gtk_plugin_container_new(); - -// Sets the size of the GtkPluginContainer. -void gtk_plugin_container_set_size(GtkWidget *widget, int width, int height); - -#endif // WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_H_ diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.cc b/webkit/glue/plugins/gtk_plugin_container_manager.cc deleted file mode 100644 index 2f82b24..0000000 --- a/webkit/glue/plugins/gtk_plugin_container_manager.cc +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/gtk_plugin_container_manager.h" - -#include - -#include "base/logging.h" -#include "gfx/gtk_util.h" -#include "webkit/glue/plugins/gtk_plugin_container.h" -#include "webkit/glue/plugins/webplugin.h" - -GtkPluginContainerManager::GtkPluginContainerManager() : host_widget_(NULL) {} - -GtkPluginContainerManager::~GtkPluginContainerManager() {} - -GtkWidget* GtkPluginContainerManager::CreatePluginContainer( - gfx::PluginWindowHandle id) { - DCHECK(host_widget_); - GtkWidget *widget = gtk_plugin_container_new(); - plugin_window_to_widget_map_.insert(std::make_pair(id, widget)); - - // The Realize callback is responsible for adding the plug into the socket. - // The reason is 2-fold: - // - the plug can't be added until the socket is realized, but this may not - // happen until the socket is attached to a top-level window, which isn't the - // case for background tabs. - // - when dragging tabs, the socket gets unrealized, which breaks the XEMBED - // connection. We need to make it again when the tab is reattached, and the - // socket gets realized again. - // - // Note, the RealizeCallback relies on the plugin_window_to_widget_map_ to - // have the mapping. - g_signal_connect(widget, "realize", - G_CALLBACK(RealizeCallback), this); - - // Don't destroy the widget when the plug is removed. - g_signal_connect(widget, "plug-removed", - G_CALLBACK(gtk_true), NULL); - - gtk_container_add(GTK_CONTAINER(host_widget_), widget); - gtk_widget_show(widget); - - return widget; -} - -void GtkPluginContainerManager::DestroyPluginContainer( - gfx::PluginWindowHandle id) { - DCHECK(host_widget_); - GtkWidget* widget = MapIDToWidget(id); - if (widget) - gtk_widget_destroy(widget); - - plugin_window_to_widget_map_.erase(id); -} - -void GtkPluginContainerManager::MovePluginContainer( - const webkit_glue::WebPluginGeometry& move) { - DCHECK(host_widget_); - GtkWidget *widget = MapIDToWidget(move.window); - if (!widget) - return; - - DCHECK(!GTK_WIDGET_NO_WINDOW(widget)); - - if (!move.visible) { - gtk_widget_hide(widget); - return; - } - - gtk_widget_show(widget); - - if (!move.rects_valid) - return; - - // TODO(piman): if the widget hasn't been realized (e.g. the tab has been - // torn off and the parent gtk widget has been detached from the hierarchy), - // we lose the cutout information. - if (GTK_WIDGET_REALIZED(widget)) { - GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle(); - GdkRegion* clip_region = gdk_region_rectangle(&clip_rect); - gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects); - gdk_window_shape_combine_region(widget->window, clip_region, 0, 0); - gdk_region_destroy(clip_region); - } - - // Update the window position. Resizing is handled by WebPluginDelegate. - // TODO(deanm): Verify that we only need to move and not resize. - // TODO(evanm): we should cache the last shape and position and skip all - // of this business in the common case where nothing has changed. - int current_x, current_y; - - // Until the above TODO is resolved, we can grab the last position - // off of the GtkFixed with a bit of hackery. - GValue value = {0}; - g_value_init(&value, G_TYPE_INT); - gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget, - "x", &value); - current_x = g_value_get_int(&value); - gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget, - "y", &value); - current_y = g_value_get_int(&value); - g_value_unset(&value); - - if (move.window_rect.x() != current_x || - move.window_rect.y() != current_y) { - // Calling gtk_fixed_move unnecessarily is a no-no, as it causes the - // parent window to repaint! - gtk_fixed_move(GTK_FIXED(host_widget_), - widget, - move.window_rect.x(), - move.window_rect.y()); - } - - gtk_plugin_container_set_size(widget, - move.window_rect.width(), - move.window_rect.height()); -} - -GtkWidget* GtkPluginContainerManager::MapIDToWidget( - gfx::PluginWindowHandle id) { - PluginWindowToWidgetMap::const_iterator i = - plugin_window_to_widget_map_.find(id); - if (i != plugin_window_to_widget_map_.end()) - return i->second; - - LOG(ERROR) << "Request for widget host for unknown window id " << id; - - return NULL; -} - -gfx::PluginWindowHandle GtkPluginContainerManager::MapWidgetToID( - GtkWidget* widget) { - for (PluginWindowToWidgetMap::const_iterator i = - plugin_window_to_widget_map_.begin(); - i != plugin_window_to_widget_map_.end(); ++i) { - if (i->second == widget) - return i->first; - } - - LOG(ERROR) << "Request for id for unknown widget"; - return 0; -} - -// static -void GtkPluginContainerManager::RealizeCallback(GtkWidget* widget, - void* user_data) { - GtkPluginContainerManager* plugin_container_manager = - static_cast(user_data); - - gfx::PluginWindowHandle id = plugin_container_manager->MapWidgetToID(widget); - if (id) - gtk_socket_add_id(GTK_SOCKET(widget), id); -} diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.h b/webkit/glue/plugins/gtk_plugin_container_manager.h deleted file mode 100644 index 7f7db8d..0000000 --- a/webkit/glue/plugins/gtk_plugin_container_manager.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_MANAGER_H_ -#define WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_MANAGER_H_ - -#include -#include - -#include "gfx/native_widget_types.h" - -typedef struct _GtkWidget GtkWidget; - -namespace webkit_glue { -struct WebPluginGeometry; -} - -// Helper class that creates and manages plugin containers (GtkSocket). -class GtkPluginContainerManager { - public: - GtkPluginContainerManager(); - ~GtkPluginContainerManager(); - - // Sets the widget that will host the plugin containers. Must be a GtkFixed. - void set_host_widget(GtkWidget *widget) { host_widget_ = widget; } - - // Creates a new plugin container, for a given plugin XID. - GtkWidget* CreatePluginContainer(gfx::PluginWindowHandle id); - - // Destroys a plugin container, given the plugin XID. - void DestroyPluginContainer(gfx::PluginWindowHandle id); - - // Takes an update from WebKit about a plugin's position and side and moves - // the plugin accordingly. - void MovePluginContainer(const webkit_glue::WebPluginGeometry& move); - - private: - // Maps a plugin XID to the corresponding container widget. - GtkWidget* MapIDToWidget(gfx::PluginWindowHandle id); - - // Maps a container widget to the corresponding plugin XID. - gfx::PluginWindowHandle MapWidgetToID(GtkWidget* widget); - - // Callback for when the plugin container gets realized, at which point it - // plugs the plugin XID. - static void RealizeCallback(GtkWidget *widget, void *user_data); - - // Parent of the plugin containers. - GtkWidget* host_widget_; - - // A map that associates plugin containers to the plugin XID. - typedef std::map PluginWindowToWidgetMap; - PluginWindowToWidgetMap plugin_window_to_widget_map_; -}; - -#endif // WEBKIT_GLUE_PLUGINS_GTK_PLUGIN_CONTAINER_MANAGER_H_ diff --git a/webkit/glue/plugins/npapi_extension_thunk.cc b/webkit/glue/plugins/npapi_extension_thunk.cc deleted file mode 100644 index 05a9c5d..0000000 --- a/webkit/glue/plugins/npapi_extension_thunk.cc +++ /dev/null @@ -1,551 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/npapi_extension_thunk.h" - -#include "base/logging.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "third_party/npapi/bindings/npapi_extensions.h" -#include "webkit/glue/plugins/plugin_instance.h" -#include "webkit/glue/plugins/webplugin.h" -#include "webkit/glue/plugins/webplugin_delegate.h" -#include "webkit/glue/webkit_glue.h" - -// FindInstance() -// Finds a PluginInstance from an NPP. -// The caller must take a reference if needed. -static NPAPI::PluginInstance* FindInstance(NPP id) { - if (id == NULL) { - NOTREACHED(); - return NULL; - } - return static_cast(id->ndata); -} - -// 2D device API --------------------------------------------------------------- - -static NPError Device2DQueryCapability(NPP id, int32_t capability, - int32_t* value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - plugin->webplugin()->delegate()->Device2DQueryCapability(capability, value); - return NPERR_NO_ERROR; - } else { - return NPERR_GENERIC_ERROR; - } -} - -static NPError Device2DQueryConfig(NPP id, - const NPDeviceConfig* request, - NPDeviceConfig* obtain) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device2DQueryConfig( - static_cast(request), - static_cast(obtain)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DInitializeContext(NPP id, - const NPDeviceConfig* config, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device2DInitializeContext( - static_cast(config), - static_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DSetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device2DSetStateContext( - static_cast(context), state, value); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DGetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t* value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device2DGetStateContext( - static_cast(context), state, value); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DFlushContext(NPP id, - NPDeviceContext* context, - NPDeviceFlushContextCallbackPtr callback, - void* user_data) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - NPError err = plugin->webplugin()->delegate()->Device2DFlushContext( - id, static_cast(context), callback, user_data); - - // Invoke the callback to inform the caller the work was done. - // TODO(brettw) this is probably not how we want this to work, this should - // happen when the frame is painted so the plugin knows when it can draw - // the next frame. - if (callback != NULL) - (*callback)(id, context, err, user_data); - - // Return any errors. - return err; - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DDestroyContext(NPP id, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device2DDestroyContext( - static_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DCreateBuffer(NPP id, - NPDeviceContext* context, - size_t size, - int32_t* buffer_id) { - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DDestroyBuffer(NPP id, - NPDeviceContext* context, - int32_t buffer_id) { - return NPERR_GENERIC_ERROR; -} - -static NPError Device2DMapBuffer(NPP id, - NPDeviceContext* context, - int32_t buffer_id, - NPDeviceBuffer* buffer) { - return NPERR_GENERIC_ERROR; -} - -// 3D device API --------------------------------------------------------------- - -static NPError Device3DQueryCapability(NPP id, int32_t capability, - int32_t* value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - plugin->webplugin()->delegate()->Device3DQueryCapability(capability, value); - return NPERR_NO_ERROR; - } else { - return NPERR_GENERIC_ERROR; - } -} - -static NPError Device3DQueryConfig(NPP id, - const NPDeviceConfig* request, - NPDeviceConfig* obtain) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DQueryConfig( - static_cast(request), - static_cast(obtain)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DInitializeContext(NPP id, - const NPDeviceConfig* config, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DInitializeContext( - static_cast(config), - static_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DSetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DSetStateContext( - static_cast(context), state, value); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DGetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t* value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DGetStateContext( - static_cast(context), state, value); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DFlushContext(NPP id, - NPDeviceContext* context, - NPDeviceFlushContextCallbackPtr callback, - void* user_data) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DFlushContext( - id, static_cast(context), callback, user_data); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DDestroyContext(NPP id, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DDestroyContext( - static_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DCreateBuffer(NPP id, - NPDeviceContext* context, - size_t size, - int32_t* buffer_id) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DCreateBuffer( - static_cast(context), size, buffer_id); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DDestroyBuffer(NPP id, - NPDeviceContext* context, - int32_t buffer_id) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DDestroyBuffer( - static_cast(context), buffer_id); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DMapBuffer(NPP id, - NPDeviceContext* context, - int32_t buffer_id, - NPDeviceBuffer* buffer) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DMapBuffer( - static_cast(context), buffer_id, buffer); - } - return NPERR_GENERIC_ERROR; -} - -// Experimental 3D device API -------------------------------------------------- - -static NPError Device3DGetNumConfigs(NPP id, int32_t* num_configs) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DGetNumConfigs(num_configs); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DGetConfigAttribs(NPP id, - int32_t config, - int32_t* attrib_list) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DGetConfigAttribs( - config, - attrib_list); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DCreateContext(NPP id, - int32_t config, - const int32_t* attrib_list, - NPDeviceContext** context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DCreateContext( - config, - attrib_list, - reinterpret_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DSynchronizeContext( - NPP id, - NPDeviceContext* context, - NPDeviceSynchronizationMode mode, - const int32_t* input_attrib_list, - int32_t* output_attrib_list, - NPDeviceSynchronizeContextCallbackPtr callback, - void* callback_data) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DSynchronizeContext( - id, - static_cast(context), - mode, - input_attrib_list, - output_attrib_list, - callback, - callback_data); - } - return NPERR_GENERIC_ERROR; -} - -static NPError Device3DRegisterCallback( - NPP id, - NPDeviceContext* context, - int32_t callback_type, - NPDeviceGenericCallbackPtr callback, - void* callback_data) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->Device3DRegisterCallback( - id, - static_cast(context), - callback_type, - callback, - callback_data); - } - return NPERR_GENERIC_ERROR; -} - -// Audio device API ------------------------------------------------------------ - -static NPError DeviceAudioQueryCapability(NPP id, int32_t capability, - int32_t* value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - plugin->webplugin()->delegate()->DeviceAudioQueryCapability(capability, - value); - return NPERR_NO_ERROR; - } else { - return NPERR_GENERIC_ERROR; - } -} - -static NPError DeviceAudioQueryConfig(NPP id, - const NPDeviceConfig* request, - NPDeviceConfig* obtain) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->DeviceAudioQueryConfig( - static_cast(request), - static_cast(obtain)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError DeviceAudioInitializeContext(NPP id, - const NPDeviceConfig* config, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->DeviceAudioInitializeContext( - static_cast(config), - static_cast(context)); - } - return NPERR_GENERIC_ERROR; -} - -static NPError DeviceAudioSetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t value) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - return plugin->webplugin()->delegate()->DeviceAudioSetStateContext( - static_cast(context), state, value); - } - return NPERR_GENERIC_ERROR; -} - -static NPError DeviceAudioGetStateContext(NPP id, - NPDeviceContext* context, - int32_t state, - intptr_t* value) { - scoped_refptr plugin(FindInstance(id)); - return plugin->webplugin()->delegate()->DeviceAudioGetStateContext( - static_cast(context), state, value); -} - -static NPError DeviceAudioFlushContext(NPP id, - NPDeviceContext* context, - NPDeviceFlushContextCallbackPtr callback, - void* user_data) { - scoped_refptr plugin(FindInstance(id)); - return plugin->webplugin()->delegate()->DeviceAudioFlushContext( - id, static_cast(context), callback, user_data); -} - -static NPError DeviceAudioDestroyContext(NPP id, - NPDeviceContext* context) { - scoped_refptr plugin(FindInstance(id)); - return plugin->webplugin()->delegate()->DeviceAudioDestroyContext( - static_cast(context)); -} -// ----------------------------------------------------------------------------- - -static NPDevice* AcquireDevice(NPP id, NPDeviceID device_id) { - static NPDevice device_2d = { - Device2DQueryCapability, - Device2DQueryConfig, - Device2DInitializeContext, - Device2DSetStateContext, - Device2DGetStateContext, - Device2DFlushContext, - Device2DDestroyContext, - Device2DCreateBuffer, - Device2DDestroyBuffer, - Device2DMapBuffer, - NULL, - NULL, - NULL, - NULL, - NULL, - }; - static NPDevice device_3d = { - Device3DQueryCapability, - Device3DQueryConfig, - Device3DInitializeContext, - Device3DSetStateContext, - Device3DGetStateContext, - Device3DFlushContext, - Device3DDestroyContext, - Device3DCreateBuffer, - Device3DDestroyBuffer, - Device3DMapBuffer, - Device3DGetNumConfigs, - Device3DGetConfigAttribs, - Device3DCreateContext, - Device3DRegisterCallback, - Device3DSynchronizeContext, - }; - static NPDevice device_audio = { - DeviceAudioQueryCapability, - DeviceAudioQueryConfig, - DeviceAudioInitializeContext, - DeviceAudioSetStateContext, - DeviceAudioGetStateContext, - DeviceAudioFlushContext, - DeviceAudioDestroyContext, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - }; - - switch (device_id) { - case NPPepper2DDevice: - return const_cast(&device_2d); - case NPPepper3DDevice: - return const_cast(&device_3d); - case NPPepperAudioDevice: - return const_cast(&device_audio); - default: - return NULL; - } -} - -static NPError ChooseFile(NPP id, - const char* mime_types, - NPChooseFileMode mode, - NPChooseFileCallback callback, - void* user_data) { - scoped_refptr plugin(FindInstance(id)); - if (!plugin) - return NPERR_GENERIC_ERROR; - - if (!plugin->webplugin()->delegate()->ChooseFile(mime_types, - static_cast(mode), - callback, user_data)) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - -static void NumberOfFindResultsChanged(NPP id, int total, bool final_result) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) { - plugin->webplugin()->delegate()->NumberOfFindResultsChanged( - total, final_result); - } -} - -static void SelectedFindResultChanged(NPP id, int index) { - scoped_refptr plugin(FindInstance(id)); - if (plugin) - plugin->webplugin()->delegate()->SelectedFindResultChanged(index); -} - -static NPWidgetExtensions* GetWidgetExtensions(NPP id) { - scoped_refptr plugin(FindInstance(id)); - if (!plugin) - return NULL; - - return plugin->webplugin()->delegate()->GetWidgetExtensions(); -} - -static NPError NPSetCursor(NPP id, NPCursorType type) { - scoped_refptr plugin(FindInstance(id)); - if (!plugin) - return NPERR_GENERIC_ERROR; - - return plugin->webplugin()->delegate()->SetCursor(type) ? - NPERR_NO_ERROR : NPERR_GENERIC_ERROR; -} - -static NPFontExtensions* GetFontExtensions(NPP id) { - scoped_refptr plugin(FindInstance(id)); - if (!plugin) - return NULL; - - return plugin->webplugin()->delegate()->GetFontExtensions(); -} - -namespace NPAPI { - -NPError GetPepperExtensionsFunctions(void* value) { - static const NPNExtensions kExtensions = { - &AcquireDevice, - &NumberOfFindResultsChanged, - &SelectedFindResultChanged, - &ChooseFile, - &GetWidgetExtensions, - &NPSetCursor, - &GetFontExtensions, - }; - - // Return a pointer to the canonical function table. - NPNExtensions* extensions = const_cast(&kExtensions); - NPNExtensions** exts = reinterpret_cast(value); - *exts = extensions; - return NPERR_NO_ERROR; -} - -} // namespace NPAPI diff --git a/webkit/glue/plugins/npapi_extension_thunk.h b/webkit/glue/plugins/npapi_extension_thunk.h deleted file mode 100644 index fada6bc..0000000 --- a/webkit/glue/plugins/npapi_extension_thunk.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_PLUGINS_NPAPI_EXTENSION_THUNK_H_ -#define WEBKIT_GLUE_PLUGINS_NPAPI_EXTENSION_THUNK_H_ - -#include "third_party/npapi/bindings/npapi_extensions.h" - -// This file implements forwarding for the NPAPI "Pepper" extensions through to -// the WebPluginDelegate associated with the plugin. - -namespace NPAPI { - -// Implements NPN_GetValue for the case of NPNVPepperExtensions. The function -// pointers in the returned structure implement all the extensions. -NPError GetPepperExtensionsFunctions(void* value); - -} // namespace NPAPI - -#endif // WEBKIT_GLUE_PLUGINS_NPAPI_EXTENSION_THUNK_H_ - - diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc deleted file mode 100644 index 1731d8a..0000000 --- a/webkit/glue/plugins/pepper_audio.cc +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/glue/plugins/pepper_audio.h" - -#include "base/logging.h" -#include "ppapi/c/dev/ppb_audio_dev.h" -#include "ppapi/c/dev/ppb_audio_trusted_dev.h" -#include "ppapi/c/pp_completion_callback.h" -#include "webkit/glue/plugins/pepper_common.h" - -namespace pepper { - -namespace { - -// PPB_AudioConfig ------------------------------------------------------------- - -uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count); - -PP_Resource CreateStereo16bit(PP_Module module_id, - PP_AudioSampleRate_Dev sample_rate, - uint32_t sample_frame_count) { - PluginModule* module = ResourceTracker::Get()->GetModule(module_id); - if (!module) - return 0; - - // TODO(brettw): Currently we don't actually check what the hardware - // supports, so just allow sample rates of the "guaranteed working" ones. - if (sample_rate != PP_AUDIOSAMPLERATE_44100 && - sample_rate != PP_AUDIOSAMPLERATE_48000) - return 0; - - // TODO(brettw): Currently we don't actually query to get a value from the - // hardware, so just validate the range. - if (RecommendSampleFrameCount(sample_frame_count) != sample_frame_count) - return 0; - - scoped_refptr config(new AudioConfig(module, - sample_rate, - sample_frame_count)); - return config->GetReference(); -} - -uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count) { - // TODO(brettw) Currently we don't actually query to get a value from the - // hardware, so we always return the input for in-range values. - if (requested_sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) - return PP_AUDIOMINSAMPLEFRAMECOUNT; - if (requested_sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT) - return PP_AUDIOMAXSAMPLEFRAMECOUNT; - return requested_sample_frame_count; -} - -PP_Bool IsAudioConfig(PP_Resource resource) { - scoped_refptr config = Resource::GetAs(resource); - return BoolToPPBool(!!config); -} - -PP_AudioSampleRate_Dev GetSampleRate(PP_Resource config_id) { - scoped_refptr config = Resource::GetAs(config_id); - return config ? config->sample_rate() : PP_AUDIOSAMPLERATE_NONE; -} - -uint32_t GetSampleFrameCount(PP_Resource config_id) { - scoped_refptr config = Resource::GetAs(config_id); - return config ? config->sample_frame_count() : 0; -} - -const PPB_AudioConfig_Dev ppb_audioconfig = { - &CreateStereo16bit, - &RecommendSampleFrameCount, - &IsAudioConfig, - &GetSampleRate, - &GetSampleFrameCount -}; - -// PPB_Audio ------------------------------------------------------------------- - -PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, - PPB_Audio_Callback user_callback, void* user_data) { - PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - if (!instance) - return 0; - if (!user_callback) - return 0; - scoped_refptr