summaryrefslogtreecommitdiff
path: root/content/browser
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-12-18 16:25:09 +0000
committerTorne (Richard Coles) <torne@google.com>2013-12-18 16:25:09 +0000
commita3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7 (patch)
treedafc1c6417406a7fbd422ad0bb890e96909ef564 /content/browser
parentd5f893c0bc79db3066bb5ae5d3d972ba1be7dd5f (diff)
downloadchromium_org-a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7.tar.gz
Merge from Chromium at DEPS revision 240154
This commit was generated by merge_to_master.py. Change-Id: I8f2ba858cf0e7f413dddedc2ae91dc37f7136c2e
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/DEPS2
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter.cc22
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter.h29
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_android.cc61
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_gtk.cc7
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_mac.mm7
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_utils_win.cc32
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_utils_win.h12
-rw-r--r--content/browser/accessibility/accessibility_tree_formatter_win.cc23
-rw-r--r--content/browser/accessibility/accessibility_ui.cc2
-rw-r--r--content/browser/accessibility/accessibility_win_browsertest.cc8
-rw-r--r--content/browser/accessibility/browser_accessibility.cc10
-rw-r--r--content/browser/accessibility/browser_accessibility.h14
-rw-r--r--content/browser/accessibility/browser_accessibility_android.cc233
-rw-r--r--content/browser/accessibility/browser_accessibility_android.h40
-rw-r--r--content/browser/accessibility/browser_accessibility_cocoa.mm6
-rw-r--r--content/browser/accessibility/browser_accessibility_gtk.cc2
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.cc68
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_win.cc18
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_win.h6
-rw-r--r--content/browser/accessibility/browser_accessibility_state_impl_win.cc2
-rw-r--r--content/browser/accessibility/browser_accessibility_win.cc588
-rw-r--r--content/browser/accessibility/browser_accessibility_win.h30
-rw-r--r--content/browser/accessibility/browser_accessibility_win_unittest.cc14
-rw-r--r--content/browser/accessibility/dump_accessibility_tree_browsertest.cc10
-rw-r--r--content/browser/android/OWNERS1
-rw-r--r--content/browser/android/browser_jni_registrar.cc7
-rw-r--r--content/browser/android/content_startup_flags.cc9
-rw-r--r--content/browser/android/content_view_core_impl.cc57
-rw-r--r--content/browser/android/content_view_core_impl.h12
-rw-r--r--content/browser/android/content_view_statics.cc4
-rw-r--r--content/browser/android/date_time_chooser_android.cc99
-rw-r--r--content/browser/android/date_time_chooser_android.h35
-rw-r--r--content/browser/android/in_process/synchronous_input_event_filter.cc4
-rw-r--r--content/browser/android/overscroll_glow.cc152
-rw-r--r--content/browser/android/overscroll_glow.h48
-rw-r--r--content/browser/android/popup_item_type_list.h23
-rw-r--r--content/browser/android/tracing_controller_android.cc67
-rw-r--r--content/browser/android/tracing_controller_android.h10
-rw-r--r--content/browser/android/web_contents_observer_android.cc10
-rw-r--r--content/browser/android/web_contents_observer_android.h10
-rw-r--r--content/browser/aura/gpu_process_transport_factory.cc10
-rw-r--r--content/browser/aura/gpu_process_transport_factory.h2
-rw-r--r--content/browser/aura/owned_mailbox.cc42
-rw-r--r--content/browser/aura/owned_mailbox.h41
-rw-r--r--content/browser/browser_child_process_host_impl.cc2
-rw-r--r--content/browser/browser_child_process_host_impl.h2
-rw-r--r--content/browser/browser_main_loop.cc4
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.cc74
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.h37
-rw-r--r--content/browser/browser_plugin/browser_plugin_host_browsertest.cc141
-rw-r--r--content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc4
-rw-r--r--content/browser/browser_plugin/test_browser_plugin_guest_delegate.h4
-rw-r--r--content/browser/browser_shutdown_profile_dumper.cc4
-rw-r--r--content/browser/browser_url_handler_impl.cc2
-rw-r--r--content/browser/child_process_security_policy_impl.cc2
-rw-r--r--content/browser/child_process_security_policy_unittest.cc2
-rw-r--r--content/browser/device_orientation/data_fetcher_impl_android.cc26
-rw-r--r--content/browser/devtools/browser_protocol.json5
-rw-r--r--content/browser/devtools/devtools_manager_unittest.cc2
-rw-r--r--content/browser/devtools/devtools_protocol_constants.cc430
-rw-r--r--content/browser/devtools/devtools_protocol_constants.h325
-rw-r--r--content/browser/devtools/devtools_resources.gyp2
-rw-r--r--content/browser/devtools/devtools_resources.target.darwin-arm.mk4
-rw-r--r--content/browser/devtools/devtools_resources.target.darwin-mips.mk4
-rw-r--r--content/browser/devtools/devtools_resources.target.darwin-x86.mk4
-rw-r--r--content/browser/devtools/devtools_resources.target.linux-arm.mk4
-rw-r--r--content/browser/devtools/devtools_resources.target.linux-mips.mk4
-rw-r--r--content/browser/devtools/devtools_resources.target.linux-x86.mk4
-rw-r--r--content/browser/devtools/devtools_tracing_handler.cc118
-rw-r--r--content/browser/devtools/devtools_tracing_handler.h26
-rw-r--r--content/browser/devtools/render_view_devtools_agent_host.cc12
-rw-r--r--content/browser/devtools/render_view_devtools_agent_host.h7
-rw-r--r--content/browser/devtools/renderer_overrides_handler.cc187
-rw-r--r--content/browser/devtools/renderer_overrides_handler.h2
-rw-r--r--content/browser/devtools/worker_devtools_manager.cc10
-rw-r--r--content/browser/dom_storage/dom_storage_context_impl.cc2
-rw-r--r--content/browser/dom_storage/dom_storage_message_filter.cc18
-rw-r--r--content/browser/dom_storage/dom_storage_message_filter.h16
-rw-r--r--content/browser/dom_storage/session_storage_database.cc3
-rw-r--r--content/browser/download/base_file.cc6
-rw-r--r--content/browser/download/base_file_unittest.cc7
-rw-r--r--content/browser/download/download_file_unittest.cc4
-rw-r--r--content/browser/download/download_manager_impl.cc2
-rw-r--r--content/browser/download/download_manager_impl_unittest.cc2
-rw-r--r--content/browser/download/drag_download_file.h1
-rw-r--r--content/browser/download/drag_download_util.cc12
-rw-r--r--content/browser/download/drag_download_util.h4
-rw-r--r--content/browser/download/file_metadata_unittest_linux.cc3
-rw-r--r--content/browser/download/mhtml_generation_browsertest.cc2
-rw-r--r--content/browser/download/save_file_manager.cc2
-rw-r--r--content/browser/download/save_package.cc4
-rw-r--r--content/browser/download/save_package.h2
-rw-r--r--content/browser/download/save_package_unittest.cc4
-rw-r--r--content/browser/fileapi/blob_url_request_job_unittest.cc4
-rw-r--r--content/browser/fileapi/dragged_file_util_unittest.cc3
-rw-r--r--content/browser/fileapi/file_system_context_unittest.cc9
-rw-r--r--content/browser/fileapi/file_system_operation_impl_unittest.cc18
-rw-r--r--content/browser/fileapi/fileapi_message_filter.cc21
-rw-r--r--content/browser/fileapi/local_file_util_unittest.cc10
-rw-r--r--content/browser/fileapi/obfuscated_file_util_unittest.cc4
-rw-r--r--content/browser/fileapi/transient_file_util_unittest.cc3
-rw-r--r--content/browser/frame_host/OWNERS1
-rw-r--r--content/browser/frame_host/frame_tree.cc48
-rw-r--r--content/browser/frame_host/frame_tree.h18
-rw-r--r--content/browser/frame_host/frame_tree_node.cc9
-rw-r--r--content/browser/frame_host/frame_tree_node.h14
-rw-r--r--content/browser/frame_host/frame_tree_unittest.cc16
-rw-r--r--content/browser/frame_host/interstitial_page_impl.cc17
-rw-r--r--content/browser/frame_host/interstitial_page_impl.h16
-rw-r--r--content/browser/frame_host/interstitial_page_navigator_impl.cc17
-rw-r--r--content/browser/frame_host/interstitial_page_navigator_impl.h33
-rw-r--r--content/browser/frame_host/navigation_controller_android.cc73
-rw-r--r--content/browser/frame_host/navigation_controller_android.h53
-rw-r--r--content/browser/frame_host/navigation_controller_impl.cc4
-rw-r--r--content/browser/frame_host/navigation_controller_impl_unittest.cc37
-rw-r--r--content/browser/frame_host/navigation_entry_impl.cc21
-rw-r--r--content/browser/frame_host/navigation_entry_impl.h18
-rw-r--r--content/browser/frame_host/navigation_entry_impl_unittest.cc8
-rw-r--r--content/browser/frame_host/navigator.cc18
-rw-r--r--content/browser/frame_host/navigator.h45
-rw-r--r--content/browser/frame_host/navigator_delegate.h22
-rw-r--r--content/browser/frame_host/navigator_impl.cc85
-rw-r--r--content/browser/frame_host/navigator_impl.h49
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.cc15
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.h37
-rw-r--r--content/browser/frame_host/render_frame_host_factory.cc8
-rw-r--r--content/browser/frame_host/render_frame_host_factory.h6
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc35
-rw-r--r--content/browser/frame_host/render_frame_host_impl.h24
-rw-r--r--content/browser/frame_host/render_frame_host_manager.cc24
-rw-r--r--content/browser/frame_host/render_frame_host_manager.h3
-rw-r--r--content/browser/frame_host/render_frame_host_manager_unittest.cc58
-rw-r--r--content/browser/frame_host/test_render_frame_host.cc20
-rw-r--r--content/browser/frame_host/test_render_frame_host.h30
-rw-r--r--content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc4
-rw-r--r--content/browser/geolocation/OWNERS4
-rw-r--r--content/browser/geolocation/fake_access_token_store.cc2
-rw-r--r--content/browser/geolocation/fake_access_token_store.h5
-rw-r--r--content/browser/geolocation/location_arbitrator_impl.cc2
-rw-r--r--content/browser/geolocation/location_arbitrator_impl.h2
-rw-r--r--content/browser/geolocation/location_arbitrator_impl_unittest.cc2
-rw-r--r--content/browser/geolocation/network_location_provider.cc14
-rw-r--r--content/browser/geolocation/network_location_provider.h12
-rw-r--r--content/browser/geolocation/network_location_request.cc16
-rw-r--r--content/browser/geolocation/network_location_request.h4
-rw-r--r--content/browser/geolocation/wifi_data.h4
-rw-r--r--content/browser/geolocation/wifi_data_provider_common.cc2
-rw-r--r--content/browser/geolocation/wifi_data_provider_common.h2
-rw-r--r--content/browser/geolocation/wifi_data_provider_win.cc38
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.cc19
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.h8
-rw-r--r--content/browser/gpu/compositor_util.cc22
-rw-r--r--content/browser/gpu/gpu_data_manager_impl_private.cc36
-rw-r--r--content/browser/gpu/gpu_ipc_browsertests.cc19
-rw-r--r--content/browser/gpu/gpu_process_host.cc12
-rw-r--r--content/browser/indexed_db/indexed_db_backing_store.cc49
-rw-r--r--content/browser/indexed_db/indexed_db_backing_store.h24
-rw-r--r--content/browser/indexed_db/indexed_db_backing_store_unittest.cc8
-rw-r--r--content/browser/indexed_db/indexed_db_browsertest.cc10
-rw-r--r--content/browser/indexed_db/indexed_db_callbacks.cc4
-rw-r--r--content/browser/indexed_db/indexed_db_callbacks.h2
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.cc6
-rw-r--r--content/browser/indexed_db/indexed_db_cursor.cc2
-rw-r--r--content/browser/indexed_db/indexed_db_cursor.h2
-rw-r--r--content/browser/indexed_db/indexed_db_database.cc38
-rw-r--r--content/browser/indexed_db/indexed_db_database.h11
-rw-r--r--content/browser/indexed_db/indexed_db_database_error.h6
-rw-r--r--content/browser/indexed_db/indexed_db_factory.cc20
-rw-r--r--content/browser/indexed_db/indexed_db_factory.h9
-rw-r--r--content/browser/indexed_db/indexed_db_factory_unittest.cc99
-rw-r--r--content/browser/indexed_db/indexed_db_fake_backing_store.cc22
-rw-r--r--content/browser/indexed_db/indexed_db_fake_backing_store.h25
-rw-r--r--content/browser/indexed_db/indexed_db_index_writer.cc4
-rw-r--r--content/browser/indexed_db/indexed_db_index_writer.h4
-rw-r--r--content/browser/indexed_db/indexed_db_leveldb_coding.cc71
-rw-r--r--content/browser/indexed_db/indexed_db_leveldb_coding.h44
-rw-r--r--content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc69
-rw-r--r--content/browser/indexed_db/indexed_db_metadata.cc13
-rw-r--r--content/browser/indexed_db/indexed_db_metadata.h16
-rw-r--r--content/browser/indexed_db/indexed_db_quota_client_unittest.cc6
-rw-r--r--content/browser/indexed_db/indexed_db_transaction.cc44
-rw-r--r--content/browser/indexed_db/indexed_db_transaction.h28
-rw-r--r--content/browser/indexed_db/indexed_db_transaction_unittest.cc82
-rw-r--r--content/browser/indexed_db/indexed_db_unittest.cc12
-rw-r--r--content/browser/indexed_db/mock_indexed_db_callbacks.cc12
-rw-r--r--content/browser/indexed_db/mock_indexed_db_callbacks.h4
-rw-r--r--content/browser/loader/async_resource_handler.cc7
-rw-r--r--content/browser/loader/async_resource_handler.h1
-rw-r--r--content/browser/loader/buffered_resource_handler.cc2
-rw-r--r--content/browser/loader/power_save_block_resource_throttle.cc4
-rw-r--r--content/browser/loader/power_save_block_resource_throttle.h1
-rw-r--r--content/browser/loader/resource_dispatcher_host_browsertest.cc10
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc21
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.h12
-rw-r--r--content/browser/loader/resource_dispatcher_host_unittest.cc4
-rw-r--r--content/browser/loader/resource_loader.cc33
-rw-r--r--content/browser/loader/resource_loader.h9
-rw-r--r--content/browser/loader/resource_request_info_impl.cc7
-rw-r--r--content/browser/loader/resource_request_info_impl.h3
-rw-r--r--content/browser/loader/resource_scheduler.cc9
-rw-r--r--content/browser/loader/resource_scheduler_unittest.cc2
-rw-r--r--content/browser/loader/throttling_resource_handler.cc45
-rw-r--r--content/browser/loader/throttling_resource_handler.h8
-rw-r--r--content/browser/media/android/browser_media_player_manager.cc146
-rw-r--r--content/browser/media/android/browser_media_player_manager.h45
-rw-r--r--content/browser/media/media_browsertest.cc4
-rw-r--r--content/browser/media/media_devices_monitor.cc (renamed from content/browser/media_devices_monitor.cc)5
-rw-r--r--content/browser/media/media_internals.cc8
-rw-r--r--content/browser/media/media_internals.h4
-rw-r--r--content/browser/media/media_internals_handler.cc4
-rw-r--r--content/browser/media/media_internals_handler.h2
-rw-r--r--content/browser/media/media_internals_proxy.cc6
-rw-r--r--content/browser/media/media_internals_proxy.h4
-rw-r--r--content/browser/media/media_internals_unittest.cc2
-rw-r--r--content/browser/media/webrtc_browsertest.cc62
-rw-r--r--content/browser/media/webrtc_identity_store_backend.cc2
-rw-r--r--content/browser/media/webrtc_internals_browsertest.cc2
-rw-r--r--content/browser/media/webrtc_internals_message_handler.cc4
-rw-r--r--content/browser/message_port_service.cc4
-rw-r--r--content/browser/message_port_service.h7
-rw-r--r--content/browser/net/sqlite_persistent_cookie_store.cc4
-rw-r--r--content/browser/net/sqlite_persistent_cookie_store_unittest.cc4
-rw-r--r--content/browser/plugin_browsertest.cc10
-rw-r--r--content/browser/plugin_loader_posix_unittest.cc6
-rw-r--r--content/browser/plugin_service_impl.cc46
-rw-r--r--content/browser/plugin_service_impl.h10
-rw-r--r--content/browser/power_save_blocker_win.cc2
-rw-r--r--content/browser/ppapi_plugin_process_host.cc17
-rw-r--r--content/browser/ppapi_plugin_process_host.h2
-rw-r--r--content/browser/renderer_host/clipboard_message_filter.cc15
-rw-r--r--content/browser/renderer_host/clipboard_message_filter.h12
-rw-r--r--content/browser/renderer_host/clipboard_message_filter_mac.mm3
-rw-r--r--content/browser/renderer_host/compositing_iosurface_mac.h2
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc2
-rw-r--r--content/browser/renderer_host/database_message_filter.cc47
-rw-r--r--content/browser/renderer_host/database_message_filter.h24
-rw-r--r--content/browser/renderer_host/file_utilities_message_filter.cc2
-rw-r--r--content/browser/renderer_host/gtk_im_context_wrapper.cc4
-rw-r--r--content/browser/renderer_host/gtk_im_context_wrapper.h4
-rw-r--r--content/browser/renderer_host/image_transport_factory_android.cc4
-rw-r--r--content/browser/renderer_host/ime_adapter_android.cc7
-rw-r--r--content/browser/renderer_host/input/gesture_event_filter.h6
-rw-r--r--content/browser/renderer_host/input/gesture_event_filter_unittest.cc4
-rw-r--r--content/browser/renderer_host/input/input_router.h9
-rw-r--r--content/browser/renderer_host/input/input_router_impl.cc (renamed from content/browser/renderer_host/input/immediate_input_router.cc)192
-rw-r--r--content/browser/renderer_host/input/input_router_impl.h (renamed from content/browser/renderer_host/input/immediate_input_router.h)35
-rw-r--r--content/browser/renderer_host/input/input_router_impl_unittest.cc (renamed from content/browser/renderer_host/input/immediate_input_router_unittest.cc)246
-rw-r--r--content/browser/renderer_host/input/input_router_unittest.cc167
-rw-r--r--content/browser/renderer_host/input/input_router_unittest.h84
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture.cc5
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc433
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target.h4
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.cc9
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_android.h2
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.cc7
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_aura.h2
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.cc9
-rw-r--r--content/browser/renderer_host/input/synthetic_gesture_target_base.h4
-rw-r--r--content/browser/renderer_host/input/synthetic_pinch_gesture.cc140
-rw-r--r--content/browser/renderer_host/input/synthetic_pinch_gesture.h35
-rw-r--r--content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc128
-rw-r--r--content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h30
-rw-r--r--content/browser/renderer_host/input/synthetic_tap_gesture.cc119
-rw-r--r--content/browser/renderer_host/input/synthetic_tap_gesture.h49
-rw-r--r--content/browser/renderer_host/input/synthetic_web_input_event_builders.cc189
-rw-r--r--content/browser/renderer_host/input/synthetic_web_input_event_builders.h83
-rw-r--r--content/browser/renderer_host/input/timeout_monitor.cc78
-rw-r--r--content/browser/renderer_host/input/timeout_monitor.h50
-rw-r--r--content/browser/renderer_host/input/touch_action_filter.cc63
-rw-r--r--content/browser/renderer_host/input/touch_action_filter.h45
-rw-r--r--content/browser/renderer_host/input/touch_action_filter_unittest.cc100
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.cc314
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.h50
-rw-r--r--content/browser/renderer_host/input/touch_event_queue_unittest.cc505
-rw-r--r--content/browser/renderer_host/input/touch_input_browsertest.cc307
-rw-r--r--content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc6
-rw-r--r--content/browser/renderer_host/java/OWNERS2
-rw-r--r--content/browser/renderer_host/java/java_bridge_dispatcher_host.cc4
-rw-r--r--content/browser/renderer_host/java/java_bridge_dispatcher_host.h4
-rw-r--r--content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc5
-rw-r--r--content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h6
-rw-r--r--content/browser/renderer_host/java/java_method.cc2
-rw-r--r--content/browser/renderer_host/media/OWNERS3
-rw-r--r--content/browser/renderer_host/media/audio_input_device_manager_unittest.cc2
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host_unittest.cc2
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_aura.cc (renamed from content/browser/renderer_host/media/desktop_capture_device_ash.cc)46
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_aura.h (renamed from content/browser/renderer_host/media/desktop_capture_device_ash.h)18
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc (renamed from content/browser/renderer_host/media/desktop_capture_device_ash_unittest.cc)16
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter.cc28
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter.h3
-rw-r--r--content/browser/renderer_host/media/device_request_message_filter_unittest.cc58
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host.cc59
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host.h9
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc388
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.cc638
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.h98
-rw-r--r--content/browser/renderer_host/media/media_stream_manager_unittest.cc12
-rw-r--r--content/browser/renderer_host/media/media_stream_ui_proxy.cc8
-rw-r--r--content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc8
-rw-r--r--content/browser/renderer_host/media/midi_host.cc135
-rw-r--r--content/browser/renderer_host/media/midi_host.h27
-rw-r--r--content/browser/renderer_host/media/midi_host_unittest.cc90
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc18
-rw-r--r--content/browser/renderer_host/media/video_capture_device_impl.cc54
-rw-r--r--content/browser/renderer_host/media/video_capture_device_impl.h17
-rw-r--r--content/browser/renderer_host/media/video_capture_host_unittest.cc15
-rw-r--r--content/browser/renderer_host/media/video_capture_manager.cc46
-rw-r--r--content/browser/renderer_host/media/video_capture_manager.h12
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc15
-rw-r--r--content/browser/renderer_host/native_web_keyboard_event_aura.cc2
-rw-r--r--content/browser/renderer_host/p2p/socket_dispatcher_host.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.cc13
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp_server.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp.cc19
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp.h2
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp_unittest.cc5
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_io_host.cc273
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_io_host.h67
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc217
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_system_browser_host.h66
-rw-r--r--content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc8
-rw-r--r--content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc2
-rw-r--r--content/browser/renderer_host/pepper/quota_file_io.cc359
-rw-r--r--content/browser/renderer_host/pepper/quota_file_io.h127
-rw-r--r--content/browser/renderer_host/pepper/quota_file_io_unittest.cc426
-rw-r--r--content/browser/renderer_host/pepper/quota_reservation.cc129
-rw-r--r--content/browser/renderer_host/pepper/quota_reservation.h100
-rw-r--r--content/browser/renderer_host/pepper/quota_reservation_unittest.cc238
-rw-r--r--content/browser/renderer_host/render_message_filter.cc122
-rw-r--r--content/browser/renderer_host/render_message_filter.h17
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc25
-rw-r--r--content/browser/renderer_host/render_sandbox_host_linux.cc15
-rw-r--r--content/browser/renderer_host/render_view_host_delegate.cc4
-rw-r--r--content/browser/renderer_host/render_view_host_delegate.h36
-rw-r--r--content/browser/renderer_host/render_view_host_factory.cc10
-rw-r--r--content/browser/renderer_host/render_view_host_factory.h3
-rw-r--r--content/browser/renderer_host/render_view_host_impl.cc77
-rw-r--r--content/browser/renderer_host/render_view_host_impl.h38
-rw-r--r--content/browser/renderer_host/render_view_host_unittest.cc4
-rw-r--r--content/browser/renderer_host/render_widget_helper.cc4
-rw-r--r--content/browser/renderer_host/render_widget_host_browsertest.cc3
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc118
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h23
-rw-r--r--content/browser/renderer_host/render_widget_host_unittest.cc33
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc143
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h16
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc105
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h23
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura_unittest.cc35
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc8
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h6
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.cc20
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.cc10
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_guest_unittest.cc2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.h42
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm154
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_unittest.mm10
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.h8
-rw-r--r--content/browser/renderer_host/test_backing_store.cc38
-rw-r--r--content/browser/renderer_host/test_backing_store.h39
-rw-r--r--content/browser/renderer_host/test_render_view_host.cc432
-rw-r--r--content/browser/renderer_host/test_render_view_host.h385
-rw-r--r--content/browser/renderer_host/web_input_event_aura.cc8
-rw-r--r--content/browser/renderer_host/webmenurunner_mac.mm8
-rw-r--r--content/browser/resource_context_impl.cc4
-rw-r--r--content/browser/resources/gpu/info_view.js1
-rw-r--r--content/browser/resources/media/dump_creator.js10
-rw-r--r--content/browser/security_exploit_browsertest.cc113
-rw-r--r--content/browser/service_worker/embedded_worker_instance.cc99
-rw-r--r--content/browser/service_worker/embedded_worker_instance.h102
-rw-r--r--content/browser/service_worker/embedded_worker_instance_unittest.cc137
-rw-r--r--content/browser/service_worker/embedded_worker_registry.cc70
-rw-r--r--content/browser/service_worker/embedded_worker_registry.h77
-rw-r--r--content/browser/service_worker/service_worker_context.h6
-rw-r--r--content/browser/service_worker/service_worker_context_core.cc73
-rw-r--r--content/browser/service_worker/service_worker_context_core.h47
-rw-r--r--content/browser/service_worker/service_worker_context_unittest.cc168
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc19
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.h4
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host_unittest.cc2
-rw-r--r--content/browser/service_worker/service_worker_register_job.cc118
-rw-r--r--content/browser/service_worker/service_worker_register_job.h79
-rw-r--r--content/browser/service_worker/service_worker_registration_status.h21
-rw-r--r--content/browser/service_worker/service_worker_registration_unittest.cc11
-rw-r--r--content/browser/service_worker/service_worker_storage.cc190
-rw-r--r--content/browser/service_worker/service_worker_storage.h102
-rw-r--r--content/browser/service_worker/service_worker_storage_unittest.cc354
-rw-r--r--content/browser/service_worker/service_worker_version.cc38
-rw-r--r--content/browser/service_worker/service_worker_version.h29
-rw-r--r--content/browser/session_history_browsertest.cc2
-rw-r--r--content/browser/site_instance_impl_unittest.cc11
-rw-r--r--content/browser/site_per_process_browsertest.cc6
-rw-r--r--content/browser/speech/google_one_shot_remote_engine.cc2
-rw-r--r--content/browser/speech/proto/speech_proto.target.darwin-arm.mk6
-rw-r--r--content/browser/speech/proto/speech_proto.target.darwin-mips.mk6
-rw-r--r--content/browser/speech/proto/speech_proto.target.darwin-x86.mk6
-rw-r--r--content/browser/speech/proto/speech_proto.target.linux-arm.mk6
-rw-r--r--content/browser/speech/proto/speech_proto.target.linux-mips.mk6
-rw-r--r--content/browser/speech/proto/speech_proto.target.linux-x86.mk6
-rw-r--r--content/browser/speech/speech_recognition_manager_impl.cc2
-rw-r--r--content/browser/speech/speech_recognition_manager_impl.h2
-rw-r--r--content/browser/speech/speech_recognizer_impl_android.cc2
-rw-r--r--content/browser/ssl/ssl_manager.cc7
-rw-r--r--content/browser/storage_partition_impl_map.cc4
-rw-r--r--content/browser/storage_partition_impl_unittest.cc18
-rw-r--r--content/browser/tracing/trace_controller_impl.cc371
-rw-r--r--content/browser/tracing/trace_controller_impl.h105
-rw-r--r--content/browser/tracing/trace_message_filter.cc23
-rw-r--r--content/browser/tracing/trace_message_filter.h2
-rw-r--r--content/browser/tracing/trace_subscriber_stdio.cc201
-rw-r--r--content/browser/tracing/trace_subscriber_stdio.h57
-rw-r--r--content/browser/tracing/trace_subscriber_stdio_unittest.cc132
-rw-r--r--content/browser/tracing/tracing_controller_browsertest.cc23
-rw-r--r--content/browser/tracing/tracing_controller_impl.cc179
-rw-r--r--content/browser/tracing/tracing_controller_impl.h39
-rw-r--r--content/browser/tracing/tracing_ui.cc5
-rw-r--r--content/browser/web_contents/touch_editable_impl_aura.cc2
-rw-r--r--content/browser/web_contents/web_contents_android.cc58
-rw-r--r--content/browser/web_contents/web_contents_android.h46
-rw-r--r--content/browser/web_contents/web_contents_delegate_unittest.cc2
-rw-r--r--content/browser/web_contents/web_contents_drag_win.cc8
-rw-r--r--content/browser/web_contents/web_contents_impl.cc307
-rw-r--r--content/browser/web_contents/web_contents_impl.h96
-rw-r--r--content/browser/web_contents/web_contents_impl_unittest.cc12
-rw-r--r--content/browser/web_contents/web_contents_view_android.cc2
-rw-r--r--content/browser/web_contents/web_contents_view_android.h2
-rw-r--r--content/browser/web_contents/web_contents_view_aura.cc10
-rw-r--r--content/browser/web_contents/web_contents_view_aura.h2
-rw-r--r--content/browser/web_contents/web_contents_view_aura_browsertest.cc24
-rw-r--r--content/browser/web_contents/web_contents_view_gtk.cc2
-rw-r--r--content/browser/web_contents/web_contents_view_gtk.h2
-rw-r--r--content/browser/web_contents/web_contents_view_guest.cc11
-rw-r--r--content/browser/web_contents/web_contents_view_guest.h5
-rw-r--r--content/browser/web_contents/web_contents_view_mac.h19
-rw-r--r--content/browser/web_contents/web_contents_view_mac.mm55
-rw-r--r--content/browser/web_contents/web_contents_view_win.cc2
-rw-r--r--content/browser/web_contents/web_contents_view_win.h2
-rw-r--r--content/browser/web_contents/web_drag_dest_gtk.cc3
-rw-r--r--content/browser/web_contents/web_drag_dest_mac.mm2
-rw-r--r--content/browser/web_contents/web_drag_dest_mac_unittest.mm4
-rw-r--r--content/browser/web_contents/web_drag_source_gtk.h2
-rw-r--r--content/browser/web_contents/web_drag_source_mac.mm10
-rw-r--r--content/browser/webui/web_ui_data_source_impl.cc2
-rw-r--r--content/browser/webui/web_ui_data_source_impl.h2
-rw-r--r--content/browser/webui/web_ui_data_source_unittest.cc4
-rw-r--r--content/browser/webui/web_ui_impl.cc12
-rw-r--r--content/browser/webui/web_ui_impl.h8
-rw-r--r--content/browser/webui/web_ui_message_handler.cc6
-rw-r--r--content/browser/webui/web_ui_message_handler_unittest.cc16
-rw-r--r--content/browser/worker_host/test/worker_browsertest.cc8
-rw-r--r--content/browser/worker_host/worker_process_host.cc12
-rw-r--r--content/browser/worker_host/worker_process_host.h16
-rw-r--r--content/browser/worker_host/worker_service_impl.cc8
-rw-r--r--content/browser/worker_host/worker_service_impl.h8
460 files changed, 12159 insertions, 7277 deletions
diff --git a/content/browser/DEPS b/content/browser/DEPS
index f97cc40386..6e6295235a 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -60,6 +60,8 @@ include_rules = [
# These should be burned down. http://crbug.com/237267
"!third_party/WebKit/public/web/mac/WebInputEventFactory.h",
+ "+ui/ozone/ozone_switches.h",
+
# DO NOT ADD ANY CHROME OR COMPONENTS INCLUDES HERE!!!
# See https://sites.google.com/a/chromium.org/dev/developers/content-module
# for more information.
diff --git a/content/browser/accessibility/accessibility_tree_formatter.cc b/content/browser/accessibility/accessibility_tree_formatter.cc
index 3e03b80433..af33a42a7c 100644
--- a/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -55,7 +55,7 @@ AccessibilityTreeFormatter::BuildAccessibilityTree() {
}
void AccessibilityTreeFormatter::FormatAccessibilityTree(
- string16* contents) {
+ base::string16* contents) {
scoped_ptr<base::DictionaryValue> dict = BuildAccessibilityTree();
RecursiveFormatAccessibilityTree(*(dict.get()), contents);
}
@@ -76,9 +76,10 @@ void AccessibilityTreeFormatter::RecursiveBuildAccessibilityTree(
}
void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree(
- const base::DictionaryValue& dict, string16* contents, int depth) {
- string16 line = ToString(dict, string16(depth * kIndentSpaces, ' '));
- if (line.find(ASCIIToUTF16(kSkipString)) != string16::npos)
+ const base::DictionaryValue& dict, base::string16* contents, int depth) {
+ base::string16 line =
+ ToString(dict, base::string16(depth * kIndentSpaces, ' '));
+ if (line.find(ASCIIToUTF16(kSkipString)) != base::string16::npos)
return;
*contents += line;
@@ -98,8 +99,9 @@ void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
dict->SetInteger("id", node.renderer_id());
}
-string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& node,
- const string16& indent) {
+base::string16 AccessibilityTreeFormatter::ToString(
+ const base::DictionaryValue& node,
+ const base::string16& indent) {
int id_value;
node.GetInteger("id", &id_value);
return indent + base::IntToString16(id_value) +
@@ -142,7 +144,7 @@ void AccessibilityTreeFormatter::SetFilters(
}
bool AccessibilityTreeFormatter::MatchesFilters(
- const string16& text, bool default_result) const {
+ const base::string16& text, bool default_result) const {
std::vector<Filter>::const_iterator iter = filters_.begin();
bool allow = default_result;
for (iter = filters_.begin(); iter != filters_.end(); ++iter) {
@@ -158,7 +160,7 @@ bool AccessibilityTreeFormatter::MatchesFilters(
return allow;
}
-string16 AccessibilityTreeFormatter::FormatCoordinates(
+base::string16 AccessibilityTreeFormatter::FormatCoordinates(
const char* name, const char* x_name, const char* y_name,
const base::DictionaryValue& value) {
int x, y;
@@ -170,12 +172,12 @@ string16 AccessibilityTreeFormatter::FormatCoordinates(
}
void AccessibilityTreeFormatter::WriteAttribute(
- bool include_by_default, const std::string& attr, string16* line) {
+ bool include_by_default, const std::string& attr, base::string16* line) {
WriteAttribute(include_by_default, UTF8ToUTF16(attr), line);
}
void AccessibilityTreeFormatter::WriteAttribute(
- bool include_by_default, const string16& attr, string16* line) {
+ bool include_by_default, const base::string16& attr, base::string16* line) {
if (attr.empty())
return;
if (!MatchesFilters(attr, include_by_default))
diff --git a/content/browser/accessibility/accessibility_tree_formatter.h b/content/browser/accessibility/accessibility_tree_formatter.h
index 006ee9a2d2..a290886aad 100644
--- a/content/browser/accessibility/accessibility_tree_formatter.h
+++ b/content/browser/accessibility/accessibility_tree_formatter.h
@@ -52,7 +52,7 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
scoped_ptr<base::DictionaryValue> BuildAccessibilityTree();
// Dumps a BrowserAccessibility tree into a string.
- void FormatAccessibilityTree(string16* contents);
+ void FormatAccessibilityTree(base::string16* contents);
// A single filter specification. See GetAllowString() and GetDenyString()
// for more information.
@@ -62,10 +62,10 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
ALLOW_EMPTY,
DENY
};
- string16 match_str;
+ base::string16 match_str;
Type type;
- Filter(string16 match_str, Type type)
+ Filter(base::string16 match_str, Type type)
: match_str(match_str), type(type) {}
};
@@ -100,12 +100,12 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
protected:
void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node,
- string16* contents,
+ base::string16* contents,
int indent);
void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
base::DictionaryValue* tree_node);
void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node,
- string16* contents,
+ base::string16* contents,
int depth = 0);
// Overridden by each platform to add the required attributes for each node
@@ -113,27 +113,28 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict);
- string16 FormatCoordinates(const char* name,
- const char* x_name,
- const char* y_name,
- const base::DictionaryValue& value);
+ base::string16 FormatCoordinates(const char* name,
+ const char* x_name,
+ const char* y_name,
+ const base::DictionaryValue& value);
// Returns a platform specific representation of a BrowserAccessibility.
// Should be zero or more complete lines, each with |prefix| prepended
// (to indent each line).
- string16 ToString(const base::DictionaryValue& node, const string16& indent);
+ base::string16 ToString(const base::DictionaryValue& node,
+ const base::string16& indent);
void Initialize();
- bool MatchesFilters(const string16& text, bool default_result) const;
+ bool MatchesFilters(const base::string16& text, bool default_result) const;
// Writes the given attribute string out to |line| if it matches the filters.
void WriteAttribute(bool include_by_default,
- const string16& attr,
- string16* line);
+ const base::string16& attr,
+ base::string16* line);
void WriteAttribute(bool include_by_default,
const std::string& attr,
- string16* line);
+ base::string16* line);
BrowserAccessibility* root_;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc
index ae34ef59c0..8c625a3eae 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -25,12 +25,20 @@ const char* BOOL_ATTRIBUTES[] = {
"checkable",
"checked",
"clickable",
+ "collection",
+ "collection_item",
+ "content_invalid",
"disabled",
+ "dismissable",
"editable_text",
"focusable",
"focused",
+ "heading",
+ "hierarchical",
"invisible",
+ "multiline",
"password",
+ "range",
"scrollable",
"selected"
};
@@ -41,7 +49,18 @@ const char* STRING_ATTRIBUTES[] = {
const char* INT_ATTRIBUTES[] = {
"item_index",
- "item_count"
+ "item_count",
+ "row_count",
+ "column_count",
+ "row_index",
+ "row_span",
+ "column_index",
+ "column_span",
+ "input_type",
+ "live_region_type",
+ "range_min",
+ "range_max",
+ "range_current_value",
};
}
@@ -57,17 +76,24 @@ void AccessibilityTreeFormatter::AddProperties(
dict->SetString("class", android_node->GetClassName());
// Bool attributes.
- dict->SetBoolean("focusable", android_node->IsFocusable());
- dict->SetBoolean("focused", android_node->IsFocused());
- dict->SetBoolean("clickable", android_node->IsClickable());
- dict->SetBoolean("editable_text", android_node->IsEditableText());
dict->SetBoolean("checkable", android_node->IsCheckable());
dict->SetBoolean("checked", android_node->IsChecked());
+ dict->SetBoolean("clickable", android_node->IsClickable());
+ dict->SetBoolean("collection", android_node->IsCollection());
+ dict->SetBoolean("collection_item", android_node->IsCollectionItem());
dict->SetBoolean("disabled", !android_node->IsEnabled());
- dict->SetBoolean("scrollable", android_node->IsScrollable());
+ dict->SetBoolean("dismissable", android_node->IsDismissable());
+ dict->SetBoolean("editable_text", android_node->IsEditableText());
+ dict->SetBoolean("focusable", android_node->IsFocusable());
+ dict->SetBoolean("focused", android_node->IsFocused());
+ dict->SetBoolean("heading", android_node->IsHeading());
+ dict->SetBoolean("hierarchical", android_node->IsHierarchical());
+ dict->SetBoolean("invisible", !android_node->IsVisibleToUser());
+ dict->SetBoolean("multiline", android_node->IsMultiLine());
+ dict->SetBoolean("range", android_node->IsRangeType());
dict->SetBoolean("password", android_node->IsPassword());
+ dict->SetBoolean("scrollable", android_node->IsScrollable());
dict->SetBoolean("selected", android_node->IsSelected());
- dict->SetBoolean("invisible", !android_node->IsVisibleToUser());
// String attributes.
dict->SetString("name", android_node->GetText());
@@ -75,13 +101,26 @@ void AccessibilityTreeFormatter::AddProperties(
// Int attributes.
dict->SetInteger("item_index", android_node->GetItemIndex());
dict->SetInteger("item_count", android_node->GetItemCount());
+ dict->SetInteger("row_count", android_node->RowCount());
+ dict->SetInteger("column_count", android_node->ColumnCount());
+ dict->SetInteger("row_index", android_node->RowIndex());
+ dict->SetInteger("row_span", android_node->RowSpan());
+ dict->SetInteger("column_index", android_node->ColumnIndex());
+ dict->SetInteger("column_span", android_node->ColumnSpan());
+ dict->SetInteger("input_type", android_node->AndroidInputType());
+ dict->SetInteger("live_region_type", android_node->AndroidLiveRegionType());
+ dict->SetInteger("range_min", static_cast<int>(android_node->RangeMin()));
+ dict->SetInteger("range_max", static_cast<int>(android_node->RangeMax()));
+ dict->SetInteger("range_current_value",
+ static_cast<int>(android_node->RangeCurrentValue()));
}
-string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& dict,
- const string16& indent) {
- string16 line;
+base::string16 AccessibilityTreeFormatter::ToString(
+ const DictionaryValue& dict,
+ const base::string16& indent) {
+ base::string16 line;
- string16 class_value;
+ base::string16 class_value;
dict.GetString("class", &class_value);
WriteAttribute(true, UTF16ToUTF8(class_value), &line);
diff --git a/content/browser/accessibility/accessibility_tree_formatter_gtk.cc b/content/browser/accessibility/accessibility_tree_formatter_gtk.cc
index 8dd6b9328a..0dc21ce124 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_gtk.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_gtk.cc
@@ -37,9 +37,10 @@ void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
dict->SetInteger("id", node.renderer_id());
}
-string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& node,
- const string16& indent) {
- string16 line;
+base::string16 AccessibilityTreeFormatter::ToString(
+ const base::DictionaryValue& node,
+ const base::string16& indent) {
+ base::string16 line;
std::string role_value;
node.GetString("role", &role_value);
if (!role_value.empty())
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index 58881b4af4..021b5fdc41 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -161,9 +161,10 @@ void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node,
dict->Set(kSizeDictAttr, PopulateSize(cocoa_node).release());
}
-string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& dict,
- const string16& indent) {
- string16 line;
+base::string16 AccessibilityTreeFormatter::ToString(
+ const base::DictionaryValue& dict,
+ const base::string16& indent) {
+ base::string16 line;
NSArray* defaultAttributes =
[NSArray arrayWithObjects:NSAccessibilityTitleAttribute,
NSAccessibilityValueAttribute,
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
index 053e39b9b0..e2cebc126c 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
@@ -20,10 +20,10 @@ class AccessibilityRoleStateMap {
public:
static AccessibilityRoleStateMap* GetInstance();
- std::map<int32, string16> ia_role_string_map;
- std::map<int32, string16> ia2_role_string_map;
- std::map<int32, string16> ia_state_string_map;
- std::map<int32, string16> ia2_state_string_map;
+ std::map<int32, base::string16> ia_role_string_map;
+ std::map<int32, base::string16> ia2_role_string_map;
+ std::map<int32, base::string16> ia_state_string_map;
+ std::map<int32, base::string16> ia2_state_string_map;
private:
AccessibilityRoleStateMap();
@@ -220,44 +220,44 @@ AccessibilityRoleStateMap::AccessibilityRoleStateMap() {
} // namespace.
-string16 IAccessibleRoleToString(int32 ia_role) {
+base::string16 IAccessibleRoleToString(int32 ia_role) {
return AccessibilityRoleStateMap::GetInstance()->ia_role_string_map[ia_role];
}
-string16 IAccessible2RoleToString(int32 ia_role) {
+base::string16 IAccessible2RoleToString(int32 ia_role) {
return AccessibilityRoleStateMap::GetInstance()->ia2_role_string_map[ia_role];
}
void IAccessibleStateToStringVector(int32 ia_state,
- std::vector<string16>* result) {
- const std::map<int32, string16>& state_string_map =
+ std::vector<base::string16>* result) {
+ const std::map<int32, base::string16>& state_string_map =
AccessibilityRoleStateMap::GetInstance()->ia_state_string_map;
- std::map<int32, string16>::const_iterator it;
+ std::map<int32, base::string16>::const_iterator it;
for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
if (it->first & ia_state)
result->push_back(it->second);
}
}
-string16 IAccessibleStateToString(int32 ia_state) {
- std::vector<string16> strings;
+base::string16 IAccessibleStateToString(int32 ia_state) {
+ std::vector<base::string16> strings;
IAccessibleStateToStringVector(ia_state, &strings);
return JoinString(strings, ',');
}
void IAccessible2StateToStringVector(int32 ia2_state,
- std::vector<string16>* result) {
- const std::map<int32, string16>& state_string_map =
+ std::vector<base::string16>* result) {
+ const std::map<int32, base::string16>& state_string_map =
AccessibilityRoleStateMap::GetInstance()->ia2_state_string_map;
- std::map<int32, string16>::const_iterator it;
+ std::map<int32, base::string16>::const_iterator it;
for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
if (it->first & ia2_state)
result->push_back(it->second);
}
}
-string16 IAccessible2StateToString(int32 ia2_state) {
- std::vector<string16> strings;
+base::string16 IAccessible2StateToString(int32 ia2_state) {
+ std::vector<base::string16> strings;
IAccessible2StateToStringVector(ia2_state, &strings);
return JoinString(strings, ',');
}
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_win.h b/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
index 1baf20d54a..86b377a64e 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
+++ b/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
@@ -13,14 +13,14 @@
namespace content {
-CONTENT_EXPORT string16 IAccessibleRoleToString(int32 ia_role);
-CONTENT_EXPORT string16 IAccessible2RoleToString(int32 ia_role);
-CONTENT_EXPORT string16 IAccessibleStateToString(int32 ia_state);
+CONTENT_EXPORT base::string16 IAccessibleRoleToString(int32 ia_role);
+CONTENT_EXPORT base::string16 IAccessible2RoleToString(int32 ia_role);
+CONTENT_EXPORT base::string16 IAccessibleStateToString(int32 ia_state);
CONTENT_EXPORT void IAccessibleStateToStringVector(
- int32 ia_state, std::vector<string16>* result);
-CONTENT_EXPORT string16 IAccessible2StateToString(int32 ia2_state);
+ int32 ia_state, std::vector<base::string16>* result);
+CONTENT_EXPORT base::string16 IAccessible2StateToString(int32 ia2_state);
CONTENT_EXPORT void IAccessible2StateToStringVector(
- int32 ia_state, std::vector<string16>* result);
+ int32 ia_state, std::vector<base::string16>* result);
} // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc
index 679843dc42..c50b52630d 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -76,7 +76,7 @@ void AccessibilityTreeFormatter::AddProperties(
if (hresult == S_OK)
dict->SetString("value", msaa_variant.m_str);
- std::vector<string16> state_strings;
+ std::vector<base::string16> state_strings;
int32 ia_state = acc_obj->ia_state();
// Avoid flakiness: these states depend on whether the window is focused
@@ -87,16 +87,16 @@ void AccessibilityTreeFormatter::AddProperties(
IAccessibleStateToStringVector(ia_state, &state_strings);
IAccessible2StateToStringVector(acc_obj->ia2_state(), &state_strings);
base::ListValue* states = new base::ListValue;
- for (std::vector<string16>::const_iterator it = state_strings.begin();
+ for (std::vector<base::string16>::const_iterator it = state_strings.begin();
it != state_strings.end();
++it) {
states->AppendString(UTF16ToUTF8(*it));
}
dict->Set("states", states);
- const std::vector<string16>& ia2_attributes = acc_obj->ia2_attributes();
+ const std::vector<base::string16>& ia2_attributes = acc_obj->ia2_attributes();
base::ListValue* attributes = new base::ListValue;
- for (std::vector<string16>::const_iterator it = ia2_attributes.begin();
+ for (std::vector<base::string16>::const_iterator it = ia2_attributes.begin();
it != ia2_attributes.end();
++it) {
attributes->AppendString(UTF16ToUTF8(*it));
@@ -199,15 +199,16 @@ void AccessibilityTreeFormatter::AddProperties(
}
}
-string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& dict,
- const string16& indent) {
- string16 line;
+base::string16 AccessibilityTreeFormatter::ToString(
+ const base::DictionaryValue& dict,
+ const base::string16& indent) {
+ base::string16 line;
- string16 role_value;
+ base::string16 role_value;
dict.GetString("role", &role_value);
WriteAttribute(true, UTF16ToUTF8(role_value), &line);
- string16 name_value;
+ base::string16 name_value;
dict.GetString("name", &name_value);
WriteAttribute(true, base::StringPrintf(L"name='%ls'", name_value.c_str()),
&line);
@@ -220,7 +221,7 @@ string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& dict,
switch (value->GetType()) {
case base::Value::TYPE_STRING: {
- string16 string_value;
+ base::string16 string_value;
value->GetAsString(&string_value);
WriteAttribute(false,
StringPrintf(L"%ls='%ls'",
@@ -257,7 +258,7 @@ string16 AccessibilityTreeFormatter::ToString(const base::DictionaryValue& dict,
for (base::ListValue::const_iterator it = list_value->begin();
it != list_value->end();
++it) {
- string16 string_value;
+ base::string16 string_value;
if ((*it)->GetAsString(&string_value))
WriteAttribute(false, string_value, &line);
}
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc
index 7808cc1c5f..5203af6ade 100644
--- a/content/browser/accessibility/accessibility_ui.cc
+++ b/content/browser/accessibility/accessibility_ui.cc
@@ -233,7 +233,7 @@ void AccessibilityUI::RequestAccessibilityTree(const base::ListValue* args) {
}
scoped_ptr<AccessibilityTreeFormatter> formatter(
AccessibilityTreeFormatter::Create(rvh));
- string16 accessibility_contents_utf16;
+ base::string16 accessibility_contents_utf16;
BrowserAccessibilityManager* manager =
host_view->GetBrowserAccessibilityManager();
if (!manager) {
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 8131513c93..bb35348ba7 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -226,7 +226,7 @@ class AccessibleChecker {
void CheckAccessibleValue(IAccessible* accessible);
void CheckAccessibleState(IAccessible* accessible);
void CheckAccessibleChildren(IAccessible* accessible);
- string16 RoleVariantToString(const base::win::ScopedVariant& role);
+ base::string16 RoleVariantToString(const base::win::ScopedVariant& role);
// Expected accessible name. Checked against IAccessible::get_accName.
std::wstring name_;
@@ -403,13 +403,13 @@ void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
}
}
-string16 AccessibleChecker::RoleVariantToString(
+base::string16 AccessibleChecker::RoleVariantToString(
const base::win::ScopedVariant& role) {
if (role.type() == VT_I4)
return IAccessibleRoleToString(V_I4(&role));
if (role.type() == VT_BSTR)
- return string16(V_BSTR(&role), SysStringLen(V_BSTR(&role)));
- return string16();
+ return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role)));
+ return base::string16();
}
} // namespace
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 45f2201771..223cd8df55 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -444,17 +444,17 @@ bool BrowserAccessibility::GetStringAttribute(
return false;
}
-string16 BrowserAccessibility::GetString16Attribute(
+base::string16 BrowserAccessibility::GetString16Attribute(
StringAttribute attribute) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
- return string16();
+ return base::string16();
return UTF8ToUTF16(value_utf8);
}
bool BrowserAccessibility::GetString16Attribute(
StringAttribute attribute,
- string16* value) const {
+ base::string16* value) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
return false;
@@ -522,7 +522,7 @@ bool BrowserAccessibility::GetHtmlAttribute(
}
bool BrowserAccessibility::GetHtmlAttribute(
- const char* html_attr, string16* value) const {
+ const char* html_attr, base::string16* value) const {
std::string value_utf8;
if (!GetHtmlAttribute(html_attr, &value_utf8))
return false;
@@ -537,7 +537,7 @@ bool BrowserAccessibility::GetAriaTristate(
*is_defined = false;
*is_mixed = false;
- string16 value;
+ base::string16 value;
if (!GetHtmlAttribute(html_attr, &value) ||
value.empty() ||
EqualsASCII(value, "undefined")) {
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 1f858f1751..1258803e37 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -165,12 +165,15 @@ class CONTENT_EXPORT BrowserAccessibility {
gfx::Rect location() const { return location_; }
BrowserAccessibilityManager* manager() const { return manager_; }
const std::string& name() const { return name_; }
+ const std::string& value() const { return value_; }
int32 renderer_id() const { return renderer_id_; }
int32 role() const { return role_; }
int32 state() const { return state_; }
- const std::string& value() const { return value_; }
bool instance_active() const { return instance_active_; }
+ void set_name(const std::string& name) { name_ = name; }
+ void set_value(const std::string& value) { value_ = value; }
+
#if defined(OS_MACOSX) && __OBJC__
BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa();
#elif defined(OS_WIN)
@@ -192,7 +195,7 @@ class CONTENT_EXPORT BrowserAccessibility {
// need to distinguish between the default value and a missing attribute),
// and another that returns the default value for that type if the
// attribute is not present. In addition, strings can be returned as
- // either std::string or string16, for convenience.
+ // either std::string or base::string16, for convenience.
bool HasBoolAttribute(AccessibilityNodeData::BoolAttribute attr) const;
bool GetBoolAttribute(AccessibilityNodeData::BoolAttribute attr) const;
@@ -217,8 +220,8 @@ class CONTENT_EXPORT BrowserAccessibility {
std::string* value) const;
bool GetString16Attribute(AccessibilityNodeData::StringAttribute attribute,
- string16* value) const;
- string16 GetString16Attribute(
+ base::string16* value) const;
+ base::string16 GetString16Attribute(
AccessibilityNodeData::StringAttribute attribute) const;
bool HasIntListAttribute(
@@ -234,7 +237,7 @@ class CONTENT_EXPORT BrowserAccessibility {
// Retrieve the value of a html attribute from the attribute map and
// returns true if found.
- bool GetHtmlAttribute(const char* attr, string16* value) const;
+ bool GetHtmlAttribute(const char* attr, base::string16* value) const;
bool GetHtmlAttribute(const char* attr, std::string* value) const;
// Utility method to handle special cases for ARIA booleans, tristates and
@@ -278,6 +281,7 @@ class CONTENT_EXPORT BrowserAccessibility {
// The parent of this object, may be NULL if we're the root object.
BrowserAccessibility* parent_;
+ private:
// The index of this within its parent object.
int32 index_in_parent_;
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 433c7a1faf..d8a401b6b6 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -9,6 +9,38 @@
#include "content/common/accessibility_messages.h"
#include "content/common/accessibility_node_data.h"
+namespace {
+
+// These are enums from android.text.InputType in Java:
+enum {
+ ANDROID_TEXT_INPUTTYPE_TYPE_NULL = 0,
+ ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME = 0x4,
+ ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME_DATE = 0x14,
+ ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME_TIME = 0x24,
+ ANDROID_TEXT_INPUTTYPE_TYPE_NUMBER = 0x2,
+ ANDROID_TEXT_INPUTTYPE_TYPE_PHONE = 0x3,
+ ANDROID_TEXT_INPUTTYPE_TYPE_TEXT = 0x1,
+ ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_URI = 0x11,
+ ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_WEB_EDIT_TEXT = 0xa1,
+ ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_WEB_EMAIL = 0xd1,
+ ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_WEB_PASSWORD = 0xe1
+};
+
+// These are enums from android.view.View in Java:
+enum {
+ ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_NONE = 0,
+ ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_POLITE = 1,
+ ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2
+};
+
+// These are enums from
+// android.view.accessibility.AccessibilityNodeInfo.RangeInfo in Java:
+enum {
+ ANDROID_VIEW_ACCESSIBILITY_RANGE_TYPE_FLOAT = 1
+};
+
+} // namespace
+
namespace content {
// static
@@ -40,7 +72,7 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
return false;
// Headings with text can drop their children.
- string16 name = GetText();
+ base::string16 name = GetText();
if (role() == blink::WebAXRoleHeading && !name.empty())
return true;
@@ -78,6 +110,33 @@ bool BrowserAccessibilityAndroid::IsClickable() const {
return (PlatformIsLeaf() && !GetText().empty());
}
+bool BrowserAccessibilityAndroid::IsCollection() const {
+ return (role() == blink::WebAXRoleGrid ||
+ role() == blink::WebAXRoleList ||
+ role() == blink::WebAXRoleListBox ||
+ role() == blink::WebAXRoleTable ||
+ role() == blink::WebAXRoleTree);
+}
+
+bool BrowserAccessibilityAndroid::IsCollectionItem() const {
+ return (role() == blink::WebAXRoleCell ||
+ role() == blink::WebAXRoleColumnHeader ||
+ role() == blink::WebAXRoleDescriptionListTerm ||
+ role() == blink::WebAXRoleListBoxOption ||
+ role() == blink::WebAXRoleListItem ||
+ role() == blink::WebAXRoleRowHeader ||
+ role() == blink::WebAXRoleTreeItem);
+}
+
+bool BrowserAccessibilityAndroid::IsContentInvalid() const {
+ std::string invalid;
+ return GetHtmlAttribute("aria-invalid", &invalid);
+}
+
+bool BrowserAccessibilityAndroid::IsDismissable() const {
+ return false; // No concept of "dismissable" on the web currently.
+}
+
bool BrowserAccessibilityAndroid::IsEnabled() const {
return HasState(blink::WebAXStateEnabled);
}
@@ -95,10 +154,31 @@ bool BrowserAccessibilityAndroid::IsFocused() const {
return manager()->GetFocus(manager()->GetRoot()) == this;
}
+bool BrowserAccessibilityAndroid::IsHeading() const {
+ return (role() == blink::WebAXRoleColumnHeader ||
+ role() == blink::WebAXRoleHeading ||
+ role() == blink::WebAXRoleRowHeader);
+}
+
+bool BrowserAccessibilityAndroid::IsHierarchical() const {
+ return (role() == blink::WebAXRoleList ||
+ role() == blink::WebAXRoleTree);
+}
+
+bool BrowserAccessibilityAndroid::IsMultiLine() const {
+ return role() == blink::WebAXRoleTextArea;
+}
+
bool BrowserAccessibilityAndroid::IsPassword() const {
return HasState(blink::WebAXStateProtected);
}
+bool BrowserAccessibilityAndroid::IsRangeType() const {
+ return (role() == blink::WebAXRoleProgressIndicator ||
+ role() == blink::WebAXRoleScrollBar ||
+ role() == blink::WebAXRoleSlider);
+}
+
bool BrowserAccessibilityAndroid::IsScrollable() const {
int dummy;
return GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X_MAX, &dummy);
@@ -112,6 +192,10 @@ bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
return !HasState(blink::WebAXStateInvisible);
}
+bool BrowserAccessibilityAndroid::CanOpenPopup() const {
+ return HasState(blink::WebAXStateHaspopup);
+}
+
const char* BrowserAccessibilityAndroid::GetClassName() const {
const char* class_name = NULL;
@@ -168,15 +252,15 @@ const char* BrowserAccessibilityAndroid::GetClassName() const {
return class_name;
}
-string16 BrowserAccessibilityAndroid::GetText() const {
+base::string16 BrowserAccessibilityAndroid::GetText() const {
if (IsIframe() ||
role() == blink::WebAXRoleWebArea) {
- return string16();
+ return base::string16();
}
- string16 description = GetString16Attribute(
+ base::string16 description = GetString16Attribute(
AccessibilityNodeData::ATTR_DESCRIPTION);
- string16 text;
+ base::string16 text;
if (!name().empty())
text = base::UTF8ToUTF16(name());
else if (!description.empty())
@@ -215,6 +299,7 @@ int BrowserAccessibilityAndroid::GetItemIndex() const {
switch(role()) {
case blink::WebAXRoleListItem:
case blink::WebAXRoleListBoxOption:
+ case blink::WebAXRoleTreeItem:
index = index_in_parent();
break;
case blink::WebAXRoleSlider:
@@ -320,7 +405,7 @@ int BrowserAccessibilityAndroid::GetTextChangeRemovedCount() const {
return (old_len - left - right);
}
-string16 BrowserAccessibilityAndroid::GetTextChangeBeforeText() const {
+base::string16 BrowserAccessibilityAndroid::GetTextChangeBeforeText() const {
return old_value_;
}
@@ -340,6 +425,113 @@ int BrowserAccessibilityAndroid::GetEditableTextLength() const {
return value().length();
}
+int BrowserAccessibilityAndroid::AndroidInputType() const {
+ std::string html_tag = GetStringAttribute(
+ AccessibilityNodeData::ATTR_HTML_TAG);
+ if (html_tag != "input")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_NULL;
+
+ std::string type;
+ if (!GetHtmlAttribute("type", &type))
+ return ANDROID_TEXT_INPUTTYPE_TYPE_TEXT;
+
+ if (type == "" || type == "text" || type == "search")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_TEXT;
+ else if (type == "date")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME_DATE;
+ else if (type == "datetime" || type == "datetime-local")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME;
+ else if (type == "email")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_WEB_EMAIL;
+ else if (type == "month")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME_DATE;
+ else if (type == "number")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_NUMBER;
+ else if (type == "password")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_WEB_PASSWORD;
+ else if (type == "tel")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_PHONE;
+ else if (type == "time")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME_TIME;
+ else if (type == "url")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_TEXT_URI;
+ else if (type == "week")
+ return ANDROID_TEXT_INPUTTYPE_TYPE_DATETIME;
+
+ return ANDROID_TEXT_INPUTTYPE_TYPE_NULL;
+}
+
+int BrowserAccessibilityAndroid::AndroidLiveRegionType() const {
+ std::string live = GetStringAttribute(
+ AccessibilityNodeData::ATTR_LIVE_STATUS);
+ if (live == "polite")
+ return ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_POLITE;
+ else if (live == "assertive")
+ return ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_ASSERTIVE;
+ return ANDROID_VIEW_VIEW_ACCESSIBILITY_LIVE_REGION_NONE;
+}
+
+int BrowserAccessibilityAndroid::AndroidRangeType() const {
+ return ANDROID_VIEW_ACCESSIBILITY_RANGE_TYPE_FLOAT;
+}
+
+int BrowserAccessibilityAndroid::RowCount() const {
+ if (role() == blink::WebAXRoleGrid ||
+ role() == blink::WebAXRoleTable) {
+ return CountChildrenWithRole(blink::WebAXRoleRow);
+ }
+
+ if (role() == blink::WebAXRoleList ||
+ role() == blink::WebAXRoleListBox ||
+ role() == blink::WebAXRoleTree) {
+ return PlatformChildCount();
+ }
+
+ return 0;
+}
+
+int BrowserAccessibilityAndroid::ColumnCount() const {
+ if (role() == blink::WebAXRoleGrid ||
+ role() == blink::WebAXRoleTable) {
+ return CountChildrenWithRole(blink::WebAXRoleColumn);
+ }
+ return 0;
+}
+
+int BrowserAccessibilityAndroid::RowIndex() const {
+ if (role() == blink::WebAXRoleListItem ||
+ role() == blink::WebAXRoleListBoxOption ||
+ role() == blink::WebAXRoleTreeItem) {
+ return index_in_parent();
+ }
+
+ return GetIntAttribute(AccessibilityNodeData::ATTR_TABLE_CELL_ROW_INDEX);
+}
+
+int BrowserAccessibilityAndroid::RowSpan() const {
+ return GetIntAttribute(AccessibilityNodeData::ATTR_TABLE_CELL_ROW_SPAN);
+}
+
+int BrowserAccessibilityAndroid::ColumnIndex() const {
+ return GetIntAttribute(AccessibilityNodeData::ATTR_TABLE_CELL_COLUMN_INDEX);
+}
+
+int BrowserAccessibilityAndroid::ColumnSpan() const {
+ return GetIntAttribute(AccessibilityNodeData::ATTR_TABLE_CELL_COLUMN_SPAN);
+}
+
+float BrowserAccessibilityAndroid::RangeMin() const {
+ return GetFloatAttribute(AccessibilityNodeData::ATTR_MIN_VALUE_FOR_RANGE);
+}
+
+float BrowserAccessibilityAndroid::RangeMax() const {
+ return GetFloatAttribute(AccessibilityNodeData::ATTR_MAX_VALUE_FOR_RANGE);
+}
+
+float BrowserAccessibilityAndroid::RangeCurrentValue() const {
+ return GetFloatAttribute(AccessibilityNodeData::ATTR_VALUE_FOR_RANGE);
+}
+
bool BrowserAccessibilityAndroid::HasFocusableChild() const {
// This is called from PlatformIsLeaf, so don't call PlatformChildCount
// from within this!
@@ -365,7 +557,7 @@ bool BrowserAccessibilityAndroid::HasOnlyStaticTextChildren() const {
}
bool BrowserAccessibilityAndroid::IsIframe() const {
- string16 html_tag = GetString16Attribute(
+ base::string16 html_tag = GetString16Attribute(
AccessibilityNodeData::ATTR_HTML_TAG);
return html_tag == ASCIIToUTF16("iframe");
}
@@ -374,16 +566,16 @@ void BrowserAccessibilityAndroid::PostInitialize() {
BrowserAccessibility::PostInitialize();
if (IsEditableText()) {
- if (base::UTF8ToUTF16(value_) != new_value_) {
+ if (base::UTF8ToUTF16(value()) != new_value_) {
old_value_ = new_value_;
- new_value_ = base::UTF8ToUTF16(value_);
+ new_value_ = base::UTF8ToUTF16(value());
}
}
- if (role_ == blink::WebAXRoleAlert && first_time_)
- manager_->NotifyAccessibilityEvent(blink::WebAXEventAlert, this);
+ if (role() == blink::WebAXRoleAlert && first_time_)
+ manager()->NotifyAccessibilityEvent(blink::WebAXEventAlert, this);
- string16 live;
+ base::string16 live;
if (GetString16Attribute(
AccessibilityNodeData::ATTR_CONTAINER_LIVE_STATUS, &live)) {
NotifyLiveRegionUpdate(live);
@@ -392,19 +584,30 @@ void BrowserAccessibilityAndroid::PostInitialize() {
first_time_ = false;
}
-void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(string16& aria_live) {
+void BrowserAccessibilityAndroid::NotifyLiveRegionUpdate(
+ base::string16& aria_live) {
if (!EqualsASCII(aria_live, aria_strings::kAriaLivePolite) &&
!EqualsASCII(aria_live, aria_strings::kAriaLiveAssertive))
return;
- string16 text = GetText();
+ base::string16 text = GetText();
if (cached_text_ != text) {
if (!text.empty()) {
- manager_->NotifyAccessibilityEvent(blink::WebAXEventShow,
+ manager()->NotifyAccessibilityEvent(blink::WebAXEventShow,
this);
}
cached_text_ = text;
}
}
+int BrowserAccessibilityAndroid::CountChildrenWithRole(
+ blink::WebAXRole role) const {
+ int count = 0;
+ for (uint32 i = 0; i < PlatformChildCount(); i++) {
+ if (PlatformGetChild(i)->role() == role)
+ count++;
+ }
+ return count;
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h
index 7cb979b64b..2968184b53 100644
--- a/content/browser/accessibility/browser_accessibility_android.h
+++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -21,16 +21,26 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
bool IsCheckable() const;
bool IsChecked() const;
bool IsClickable() const;
+ bool IsCollection() const;
+ bool IsCollectionItem() const;
+ bool IsContentInvalid() const;
+ bool IsDismissable() const;
bool IsEnabled() const;
bool IsFocusable() const;
bool IsFocused() const;
+ bool IsHeading() const;
+ bool IsHierarchical() const;
+ bool IsMultiLine() const;
bool IsPassword() const;
+ bool IsRangeType() const;
bool IsScrollable() const;
bool IsSelected() const;
bool IsVisibleToUser() const;
+ bool CanOpenPopup() const;
+
const char* GetClassName() const;
- string16 GetText() const;
+ base::string16 GetText() const;
int GetItemIndex() const;
int GetItemCount() const;
@@ -43,12 +53,28 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
int GetTextChangeFromIndex() const;
int GetTextChangeAddedCount() const;
int GetTextChangeRemovedCount() const;
- string16 GetTextChangeBeforeText() const;
+ base::string16 GetTextChangeBeforeText() const;
int GetSelectionStart() const;
int GetSelectionEnd() const;
int GetEditableTextLength() const;
+ int AndroidInputType() const;
+ int AndroidLiveRegionType() const;
+ int AndroidRangeType() const;
+
+ int RowCount() const;
+ int ColumnCount() const;
+
+ int RowIndex() const;
+ int RowSpan() const;
+ int ColumnIndex() const;
+ int ColumnSpan() const;
+
+ float RangeMin() const;
+ float RangeMax() const;
+ float RangeCurrentValue() const;
+
private:
// This gives BrowserAccessibility::Create access to the class constructor.
friend class BrowserAccessibility;
@@ -59,12 +85,14 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
bool HasOnlyStaticTextChildren() const;
bool IsIframe() const;
- void NotifyLiveRegionUpdate(string16& aria_live);
+ void NotifyLiveRegionUpdate(base::string16& aria_live);
+
+ int CountChildrenWithRole(blink::WebAXRole role) const;
- string16 cached_text_;
+ base::string16 cached_text_;
bool first_time_;
- string16 old_value_;
- string16 new_value_;
+ base::string16 old_value_;
+ base::string16 new_value_;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityAndroid);
};
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 15ac608447..9364dbbfc0 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -569,7 +569,7 @@ NSDictionary* attributeToMethodNameMap = nil;
}
- (NSString*)invalid {
- string16 invalidUTF;
+ base::string16 invalidUTF;
if (!browserAccessibility_->GetHtmlAttribute("aria-invalid", &invalidUTF))
return NULL;
NSString* invalid = base::SysUTF16ToNSString(invalidUTF);
@@ -1296,10 +1296,10 @@ NSDictionary* attributeToMethodNameMap = nil;
nil]];
} else if ([role isEqualToString:NSAccessibilityRowRole]) {
if (browserAccessibility_->parent()) {
- string16 parentRole;
+ base::string16 parentRole;
browserAccessibility_->parent()->GetHtmlAttribute(
"role", &parentRole);
- const string16 treegridRole(ASCIIToUTF16("treegrid"));
+ const base::string16 treegridRole(ASCIIToUTF16("treegrid"));
if (parentRole == treegridRole) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityDisclosingAttribute,
diff --git a/content/browser/accessibility/browser_accessibility_gtk.cc b/content/browser/accessibility/browser_accessibility_gtk.cc
index c89aa2b63e..06a164cb92 100644
--- a/content/browser/accessibility/browser_accessibility_gtk.cc
+++ b/content/browser/accessibility/browser_accessibility_gtk.cc
@@ -475,7 +475,7 @@ bool BrowserAccessibilityGtk::IsNative() const {
}
void BrowserAccessibilityGtk::InitRoleAndState() {
- switch(role_) {
+ switch(role()) {
case blink::WebAXRoleDocument:
case blink::WebAXRoleRootWebArea:
case blink::WebAXRoleWebArea:
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 7cd6e85565..63f461c859 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -229,6 +229,40 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
absolute_rect.width(), absolute_rect.height(),
is_root);
+ // New KitKat APIs
+ Java_BrowserAccessibilityManager_setAccessibilityNodeInfoKitKatAttributes(
+ env, obj, info,
+ node->CanOpenPopup(),
+ node->IsContentInvalid(),
+ node->IsDismissable(),
+ node->IsMultiLine(),
+ node->AndroidInputType(),
+ node->AndroidLiveRegionType());
+ if (node->IsCollection()) {
+ Java_BrowserAccessibilityManager_setAccessibilityNodeInfoCollectionInfo(
+ env, obj, info,
+ node->RowCount(),
+ node->ColumnCount(),
+ node->IsHierarchical());
+ }
+ if (node->IsCollectionItem() || node->IsHeading()) {
+ Java_BrowserAccessibilityManager_setAccessibilityNodeInfoCollectionItemInfo(
+ env, obj, info,
+ node->RowIndex(),
+ node->RowSpan(),
+ node->ColumnIndex(),
+ node->ColumnSpan(),
+ node->IsHeading());
+ }
+ if (node->IsRangeType()) {
+ Java_BrowserAccessibilityManager_setAccessibilityNodeInfoRangeInfo(
+ env, obj, info,
+ node->AndroidRangeType(),
+ node->RangeMin(),
+ node->RangeMax(),
+ node->RangeCurrentValue());
+ }
+
return true;
}
@@ -282,6 +316,40 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityEvent(
break;
}
+ // Backwards-compatible fallback for new KitKat APIs.
+ Java_BrowserAccessibilityManager_setAccessibilityEventKitKatAttributes(
+ env, obj, event,
+ node->CanOpenPopup(),
+ node->IsContentInvalid(),
+ node->IsDismissable(),
+ node->IsMultiLine(),
+ node->AndroidInputType(),
+ node->AndroidLiveRegionType());
+ if (node->IsCollection()) {
+ Java_BrowserAccessibilityManager_setAccessibilityEventCollectionInfo(
+ env, obj, event,
+ node->RowCount(),
+ node->ColumnCount(),
+ node->IsHierarchical());
+ }
+ if (node->IsCollectionItem() || node->IsHeading()) {
+ Java_BrowserAccessibilityManager_setAccessibilityEventCollectionItemInfo(
+ env, obj, event,
+ node->RowIndex(),
+ node->RowSpan(),
+ node->ColumnIndex(),
+ node->ColumnSpan(),
+ node->IsHeading());
+ }
+ if (node->IsRangeType()) {
+ Java_BrowserAccessibilityManager_setAccessibilityEventRangeInfo(
+ env, obj, event,
+ node->AndroidRangeType(),
+ node->RangeMin(),
+ node->RangeMax(),
+ node->RangeCurrentValue());
+ }
+
return true;
}
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 5158935c31..d4dbe6dde2 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -64,6 +64,12 @@ class AccessibleHWND
IAccessible* window_accessible() { return window_accessible_; }
+ protected:
+ virtual void OnFinalMessage(HWND hwnd) OVERRIDE {
+ manager_->OnAccessibleHwndDeleted();
+ delete this;
+ }
+
private:
LRESULT OnGetObject(UINT message,
WPARAM w_param,
@@ -109,7 +115,8 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
parent_iaccessible_(parent_iaccessible),
tracked_scroll_object_(NULL),
is_chrome_frame_(
- CommandLine::ForCurrentProcess()->HasSwitch("chrome-frame")) {
+ CommandLine::ForCurrentProcess()->HasSwitch("chrome-frame")),
+ accessible_hwnd_(NULL) {
}
BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
@@ -143,9 +150,8 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event,
// accessibility tree. See comments above AccessibleHWND for details.
if (BrowserAccessibilityStateImpl::GetInstance()->IsAccessibleBrowser() &&
!is_chrome_frame_ &&
- !accessible_hwnd_ &&
- base::win::GetVersion() < base::win::VERSION_WIN8) {
- accessible_hwnd_.reset(new AccessibleHWND(parent_hwnd_, this));
+ !accessible_hwnd_) {
+ accessible_hwnd_ = new AccessibleHWND(parent_hwnd_, this);
parent_hwnd_ = accessible_hwnd_->hwnd();
parent_iaccessible_ = accessible_hwnd_->window_accessible();
}
@@ -298,4 +304,8 @@ BrowserAccessibilityWin* BrowserAccessibilityManagerWin::GetFromUniqueIdWin(
return NULL;
}
+void BrowserAccessibilityManagerWin::OnAccessibleHwndDeleted() {
+ accessible_hwnd_ = NULL;
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h
index c1887c477f..cbfc877909 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -58,6 +58,9 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// unique id, does not make a new reference.
BrowserAccessibilityWin* GetFromUniqueIdWin(LONG unique_id_win);
+ // Called when |accessible_hwnd_| is deleted by its parent.
+ void OnAccessibleHwndDeleted();
+
private:
// The closest ancestor HWND.
HWND parent_hwnd_;
@@ -79,7 +82,8 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
bool is_chrome_frame_;
- scoped_ptr<AccessibleHWND> accessible_hwnd_;
+ // Owned by its parent; OnAccessibleHwndDeleted gets called upon deletion.
+ AccessibleHWND* accessible_hwnd_;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerWin);
};
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
index 824055f6e5..28f05e0e7e 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl_win.cc
+++ b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -57,7 +57,7 @@ void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
for (size_t i = 0; i < module_count; i++) {
TCHAR filename[MAX_PATH];
GetModuleFileName(modules[i], filename, sizeof(filename));
- string16 module_name(base::FilePath(filename).BaseName().value());
+ base::string16 module_name(base::FilePath(filename).BaseName().value());
if (LowerCaseEqualsASCII(module_name, "fsdomsrv.dll"))
jaws = true;
if (LowerCaseEqualsASCII(module_name, "vbufbackend_gecko_ia2.dll"))
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index fb4c32e700..b43154a06e 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -58,7 +58,7 @@ class BrowserAccessibilityRelation
CONTENT_EXPORT virtual ~BrowserAccessibilityRelation() {}
CONTENT_EXPORT void Initialize(BrowserAccessibilityWin* owner,
- const string16& type);
+ const base::string16& type);
CONTENT_EXPORT void AddTarget(int target_id);
// IAccessibleRelation methods.
@@ -75,13 +75,13 @@ class BrowserAccessibilityRelation
}
private:
- string16 type_;
+ base::string16 type_;
base::win::ScopedComPtr<BrowserAccessibilityWin> owner_;
std::vector<int> target_ids_;
};
void BrowserAccessibilityRelation::Initialize(BrowserAccessibilityWin* owner,
- const string16& type) {
+ const base::string16& type) {
owner_ = owner;
type_ = type;
}
@@ -217,27 +217,27 @@ BrowserAccessibilityWin::~BrowserAccessibilityWin() {
// IAccessible methods.
//
// Conventions:
-// * Always test for instance_active_ first and return E_FAIL if it's false.
+// * Always test for instance_active() first and return E_FAIL if it's false.
// * Always check for invalid arguments first, even if they're unused.
// * Return S_FALSE if the only output is a string argument and it's empty.
//
HRESULT BrowserAccessibilityWin::accDoDefaultAction(VARIANT var_id) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
BrowserAccessibilityWin* target = GetTargetFromChildID(var_id);
if (!target)
return E_INVALIDARG;
- manager_->DoDefaultAction(*target);
+ manager()->DoDefaultAction(*target);
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left,
LONG y_top,
VARIANT* child) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!child)
@@ -267,7 +267,7 @@ STDMETHODIMP BrowserAccessibilityWin::accLocation(LONG* x_left,
LONG* width,
LONG* height,
VARIANT var_id) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!x_left || !y_top || !width || !height)
@@ -337,7 +337,7 @@ STDMETHODIMP BrowserAccessibilityWin::accNavigate(LONG nav_dir,
STDMETHODIMP BrowserAccessibilityWin::get_accChild(VARIANT var_child,
IDispatch** disp_child) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!disp_child)
@@ -354,7 +354,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accChild(VARIANT var_child,
}
STDMETHODIMP BrowserAccessibilityWin::get_accChildCount(LONG* child_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!child_count)
@@ -367,7 +367,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accChildCount(LONG* child_count) {
STDMETHODIMP BrowserAccessibilityWin::get_accDefaultAction(VARIANT var_id,
BSTR* def_action) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!def_action)
@@ -383,7 +383,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accDefaultAction(VARIANT var_id,
STDMETHODIMP BrowserAccessibilityWin::get_accDescription(VARIANT var_id,
BSTR* desc) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!desc)
@@ -398,14 +398,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_accDescription(VARIANT var_id,
}
STDMETHODIMP BrowserAccessibilityWin::get_accFocus(VARIANT* focus_child) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!focus_child)
return E_INVALIDARG;
BrowserAccessibilityWin* focus = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFocus(this));
+ manager()->GetFocus(this));
if (focus == this) {
focus_child->vt = VT_I4;
focus_child->lVal = CHILDID_SELF;
@@ -420,7 +420,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accFocus(VARIANT* focus_child) {
}
STDMETHODIMP BrowserAccessibilityWin::get_accHelp(VARIANT var_id, BSTR* help) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!help)
@@ -436,7 +436,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accHelp(VARIANT var_id, BSTR* help) {
STDMETHODIMP BrowserAccessibilityWin::get_accKeyboardShortcut(VARIANT var_id,
BSTR* acc_key) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!acc_key)
@@ -451,7 +451,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accKeyboardShortcut(VARIANT var_id,
}
STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!name)
@@ -469,7 +469,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) {
if (target->GetIntAttribute(AccessibilityNodeData::ATTR_TITLE_UI_ELEMENT,
&title_elem_id)) {
BrowserAccessibility* title_elem =
- manager_->GetFromRendererID(title_elem_id);
+ manager()->GetFromRendererID(title_elem_id);
if (title_elem)
name_str = title_elem->GetTextRecursive();
}
@@ -485,31 +485,33 @@ STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) {
}
STDMETHODIMP BrowserAccessibilityWin::get_accParent(IDispatch** disp_parent) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!disp_parent)
return E_INVALIDARG;
- IAccessible* parent = parent_->ToBrowserAccessibilityWin();
- if (parent == NULL) {
+ IAccessible* parent_obj = parent()->ToBrowserAccessibilityWin();
+ if (parent_obj == NULL) {
// This happens if we're the root of the tree;
// return the IAccessible for the window.
- parent = manager_->ToBrowserAccessibilityManagerWin()->parent_iaccessible();
+ parent_obj =
+ manager()->ToBrowserAccessibilityManagerWin()->parent_iaccessible();
+
// |parent| can only be NULL if the manager was created before the parent
// IAccessible was known and it wasn't subsequently set before a client
// requested it. Crash hard if this happens so that we get crash reports.
- CHECK(parent);
+ CHECK(parent_obj);
}
- parent->AddRef();
- *disp_parent = parent;
+ parent_obj->AddRef();
+ *disp_parent = parent_obj;
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_accRole(VARIANT var_id,
VARIANT* role) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!role)
@@ -531,7 +533,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accRole(VARIANT var_id,
STDMETHODIMP BrowserAccessibilityWin::get_accState(VARIANT var_id,
VARIANT* state) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!state)
@@ -543,7 +545,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accState(VARIANT var_id,
state->vt = VT_I4;
state->lVal = target->ia_state_;
- if (manager_->GetFocus(NULL) == this)
+ if (manager()->GetFocus(NULL) == this)
state->lVal |= STATE_SYSTEM_FOCUSED;
return S_OK;
@@ -551,7 +553,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accState(VARIANT var_id,
STDMETHODIMP BrowserAccessibilityWin::get_accValue(VARIANT var_id,
BSTR* value) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!value)
@@ -564,7 +566,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accValue(VARIANT var_id,
if (target->ia_role() == ROLE_SYSTEM_PROGRESSBAR ||
target->ia_role() == ROLE_SYSTEM_SCROLLBAR ||
target->ia_role() == ROLE_SYSTEM_SLIDER) {
- string16 value_text = target->GetValueText();
+ base::string16 value_text = target->GetValueText();
*value = SysAllocString(value_text.c_str());
DCHECK(*value);
return S_OK;
@@ -578,7 +580,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accValue(VARIANT var_id,
AccessibilityNodeData::ATTR_COLOR_VALUE_GREEN);
int b = target->GetIntAttribute(
AccessibilityNodeData::ATTR_COLOR_VALUE_BLUE);
- string16 value_text;
+ base::string16 value_text;
value_text = base::IntToString16((r * 100) / 255) + L"% red " +
base::IntToString16((g * 100) / 255) + L"% green " +
base::IntToString16((b * 100) / 255) + L"% blue";
@@ -599,15 +601,15 @@ STDMETHODIMP BrowserAccessibilityWin::get_accHelpTopic(BSTR* help_file,
}
STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
- if (role_ != blink::WebAXRoleListBox)
+ if (blink_role() != blink::WebAXRoleListBox)
return E_NOTIMPL;
unsigned long selected_count = 0;
- for (size_t i = 0; i < children_.size(); ++i) {
- if (children_[i]->HasState(blink::WebAXStateSelected))
+ for (size_t i = 0; i < children().size(); ++i) {
+ if (children()[i]->HasState(blink::WebAXStateSelected))
++selected_count;
}
@@ -617,11 +619,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
}
if (selected_count == 1) {
- for (size_t i = 0; i < children_.size(); ++i) {
- if (children_[i]->HasState(blink::WebAXStateSelected)) {
+ for (size_t i = 0; i < children().size(); ++i) {
+ if (children()[i]->HasState(blink::WebAXStateSelected)) {
selected->vt = VT_DISPATCH;
selected->pdispVal =
- children_[i]->ToBrowserAccessibilityWin()->NewReference();
+ children()[i]->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
}
@@ -632,11 +634,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
new base::win::EnumVariant(selected_count);
enum_variant->AddRef();
unsigned long index = 0;
- for (size_t i = 0; i < children_.size(); ++i) {
- if (children_[i]->HasState(blink::WebAXStateSelected)) {
+ for (size_t i = 0; i < children().size(); ++i) {
+ if (children()[i]->HasState(blink::WebAXStateSelected)) {
enum_variant->ItemAt(index)->vt = VT_DISPATCH;
enum_variant->ItemAt(index)->pdispVal =
- children_[i]->ToBrowserAccessibilityWin()->NewReference();
+ children()[i]->ToBrowserAccessibilityWin()->NewReference();
++index;
}
}
@@ -648,11 +650,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
STDMETHODIMP BrowserAccessibilityWin::accSelect(
LONG flags_sel, VARIANT var_id) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (flags_sel & SELFLAG_TAKEFOCUS) {
- manager_->SetFocus(this, true);
+ manager()->SetFocus(this, true);
return S_OK;
}
@@ -664,7 +666,7 @@ STDMETHODIMP BrowserAccessibilityWin::accSelect(
//
STDMETHODIMP BrowserAccessibilityWin::role(LONG* role) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!role)
@@ -676,7 +678,7 @@ STDMETHODIMP BrowserAccessibilityWin::role(LONG* role) {
}
STDMETHODIMP BrowserAccessibilityWin::get_attributes(BSTR* attributes) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!attributes)
@@ -684,7 +686,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributes(BSTR* attributes) {
// The iaccessible2 attributes are a set of key-value pairs
// separated by semicolons, with a colon between the key and the value.
- string16 str;
+ base::string16 str;
for (unsigned int i = 0; i < ia2_attributes_.size(); ++i) {
if (i != 0)
str += L';';
@@ -700,7 +702,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributes(BSTR* attributes) {
}
STDMETHODIMP BrowserAccessibilityWin::get_states(AccessibleStates* states) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!states)
@@ -712,7 +714,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_states(AccessibleStates* states) {
}
STDMETHODIMP BrowserAccessibilityWin::get_uniqueID(LONG* unique_id) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!unique_id)
@@ -723,29 +725,29 @@ STDMETHODIMP BrowserAccessibilityWin::get_uniqueID(LONG* unique_id) {
}
STDMETHODIMP BrowserAccessibilityWin::get_windowHandle(HWND* window_handle) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!window_handle)
return E_INVALIDARG;
- *window_handle = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd();
+ *window_handle = manager()->ToBrowserAccessibilityManagerWin()->parent_hwnd();
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_indexInParent(LONG* index_in_parent) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!index_in_parent)
return E_INVALIDARG;
- *index_in_parent = index_in_parent_;
+ *index_in_parent = this->index_in_parent();
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_nRelations(LONG* n_relations) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_relations)
@@ -758,7 +760,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nRelations(LONG* n_relations) {
STDMETHODIMP BrowserAccessibilityWin::get_relation(
LONG relation_index,
IAccessibleRelation** relation) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (relation_index < 0 ||
@@ -778,7 +780,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_relations(
LONG max_relations,
IAccessibleRelation** relations,
LONG* n_relations) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!relations || !n_relations)
@@ -798,41 +800,41 @@ STDMETHODIMP BrowserAccessibilityWin::get_relations(
}
STDMETHODIMP BrowserAccessibilityWin::scrollTo(enum IA2ScrollType scroll_type) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
- gfx::Rect r = location_;
+ gfx::Rect r = location();
switch(scroll_type) {
case IA2_SCROLL_TYPE_TOP_LEFT:
- manager_->ScrollToMakeVisible(*this, gfx::Rect(r.x(), r.y(), 0, 0));
+ manager()->ScrollToMakeVisible(*this, gfx::Rect(r.x(), r.y(), 0, 0));
break;
case IA2_SCROLL_TYPE_BOTTOM_RIGHT:
- manager_->ScrollToMakeVisible(
+ manager()->ScrollToMakeVisible(
*this, gfx::Rect(r.right(), r.bottom(), 0, 0));
break;
case IA2_SCROLL_TYPE_TOP_EDGE:
- manager_->ScrollToMakeVisible(
+ manager()->ScrollToMakeVisible(
*this, gfx::Rect(r.x(), r.y(), r.width(), 0));
break;
case IA2_SCROLL_TYPE_BOTTOM_EDGE:
- manager_->ScrollToMakeVisible(
+ manager()->ScrollToMakeVisible(
*this, gfx::Rect(r.x(), r.bottom(), r.width(), 0));
break;
case IA2_SCROLL_TYPE_LEFT_EDGE:
- manager_->ScrollToMakeVisible(
+ manager()->ScrollToMakeVisible(
*this, gfx::Rect(r.x(), r.y(), 0, r.height()));
break;
case IA2_SCROLL_TYPE_RIGHT_EDGE:
- manager_->ScrollToMakeVisible(
+ manager()->ScrollToMakeVisible(
*this, gfx::Rect(r.right(), r.y(), 0, r.height()));
break;
case IA2_SCROLL_TYPE_ANYWHERE:
default:
- manager_->ScrollToMakeVisible(*this, r);
+ manager()->ScrollToMakeVisible(*this, r);
break;
}
- manager_->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
+ manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
return S_OK;
}
@@ -841,22 +843,22 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToPoint(
enum IA2CoordinateType coordinate_type,
LONG x,
LONG y) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
gfx::Point scroll_to(x, y);
if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
- scroll_to -= manager_->GetViewBounds().OffsetFromOrigin();
+ scroll_to -= manager()->GetViewBounds().OffsetFromOrigin();
} else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) {
- if (parent_)
- scroll_to += parent_->location().OffsetFromOrigin();
+ if (parent())
+ scroll_to += parent()->location().OffsetFromOrigin();
} else {
return E_INVALIDARG;
}
- manager_->ScrollToPoint(*this, scroll_to);
- manager_->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
+ manager()->ScrollToPoint(*this, scroll_to);
+ manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
return S_OK;
}
@@ -865,18 +867,18 @@ STDMETHODIMP BrowserAccessibilityWin::get_groupPosition(
LONG* group_level,
LONG* similar_items_in_group,
LONG* position_in_group) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!group_level || !similar_items_in_group || !position_in_group)
return E_INVALIDARG;
- if (role_ == blink::WebAXRoleListBoxOption &&
- parent_ &&
- parent_->role() == blink::WebAXRoleListBox) {
+ if (blink_role() == blink::WebAXRoleListBoxOption &&
+ parent() &&
+ parent()->role() == blink::WebAXRoleListBox) {
*group_level = 0;
- *similar_items_in_group = parent_->PlatformChildCount();
- *position_in_group = index_in_parent_ + 1;
+ *similar_items_in_group = parent()->PlatformChildCount();
+ *position_in_group = index_in_parent() + 1;
return S_OK;
}
@@ -888,7 +890,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_groupPosition(
//
STDMETHODIMP BrowserAccessibilityWin::get_appName(BSTR* app_name) {
- // No need to check |instance_active_| because this interface is
+ // No need to check |instance_active()| because this interface is
// global, and doesn't depend on any local state.
if (!app_name)
@@ -907,7 +909,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_appName(BSTR* app_name) {
}
STDMETHODIMP BrowserAccessibilityWin::get_appVersion(BSTR* app_version) {
- // No need to check |instance_active_| because this interface is
+ // No need to check |instance_active()| because this interface is
// global, and doesn't depend on any local state.
if (!app_version)
@@ -926,7 +928,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_appVersion(BSTR* app_version) {
}
STDMETHODIMP BrowserAccessibilityWin::get_toolkitName(BSTR* toolkit_name) {
- // No need to check |instance_active_| because this interface is
+ // No need to check |instance_active()| because this interface is
// global, and doesn't depend on any local state.
if (!toolkit_name)
@@ -942,7 +944,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_toolkitName(BSTR* toolkit_name) {
STDMETHODIMP BrowserAccessibilityWin::get_toolkitVersion(
BSTR* toolkit_version) {
- // No need to check |instance_active_| because this interface is
+ // No need to check |instance_active()| because this interface is
// global, and doesn't depend on any local state.
if (!toolkit_version)
@@ -959,7 +961,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_toolkitVersion(
//
STDMETHODIMP BrowserAccessibilityWin::get_description(BSTR* desc) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!desc)
@@ -973,7 +975,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_imagePosition(
enum IA2CoordinateType coordinate_type,
LONG* x,
LONG* y) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!x || !y)
@@ -981,17 +983,17 @@ STDMETHODIMP BrowserAccessibilityWin::get_imagePosition(
if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
HWND parent_hwnd =
- manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd();
+ manager()->ToBrowserAccessibilityManagerWin()->parent_hwnd();
POINT top_left = {0, 0};
::ClientToScreen(parent_hwnd, &top_left);
- *x = location_.x() + top_left.x;
- *y = location_.y() + top_left.y;
+ *x = location().x() + top_left.x;
+ *y = location().y() + top_left.y;
} else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) {
- *x = location_.x();
- *y = location_.y();
- if (parent_) {
- *x -= parent_->location().x();
- *y -= parent_->location().y();
+ *x = location().x();
+ *y = location().y();
+ if (parent()) {
+ *x -= parent()->location().x();
+ *y -= parent()->location().y();
}
} else {
return E_INVALIDARG;
@@ -1001,14 +1003,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_imagePosition(
}
STDMETHODIMP BrowserAccessibilityWin::get_imageSize(LONG* height, LONG* width) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!height || !width)
return E_INVALIDARG;
- *height = location_.height();
- *width = location_.width();
+ *height = location().height();
+ *width = location().width();
return S_OK;
}
@@ -1020,7 +1022,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accessibleAt(
long row,
long column,
IUnknown** accessible) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!accessible)
@@ -1056,7 +1058,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accessibleAt(
}
STDMETHODIMP BrowserAccessibilityWin::get_caption(IUnknown** accessible) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!accessible)
@@ -1069,7 +1071,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_caption(IUnknown** accessible) {
STDMETHODIMP BrowserAccessibilityWin::get_childIndex(long row,
long column,
long* cell_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!cell_index)
@@ -1107,7 +1109,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_childIndex(long row,
STDMETHODIMP BrowserAccessibilityWin::get_columnDescription(long column,
BSTR* description) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!description)
@@ -1131,9 +1133,9 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnDescription(long column,
for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids[i * columns + column];
BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
- if (cell && cell->role_ == blink::WebAXRoleColumnHeader) {
- string16 cell_name = cell->GetString16Attribute(
+ manager()->GetFromRendererID(cell_id));
+ if (cell && cell->blink_role() == blink::WebAXRoleColumnHeader) {
+ base::string16 cell_name = cell->GetString16Attribute(
AccessibilityNodeData::ATTR_NAME);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
@@ -1152,7 +1154,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnExtentAt(
long row,
long column,
long* n_columns_spanned) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_columns_spanned)
@@ -1175,7 +1177,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnExtentAt(
AccessibilityNodeData::ATTR_CELL_IDS);
int cell_id = cell_ids[row * columns + column];
BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ manager()->GetFromRendererID(cell_id));
int colspan;
if (cell &&
cell->GetIntAttribute(
@@ -1197,7 +1199,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeader(
STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long cell_index,
long* column_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!column_index)
@@ -1213,7 +1215,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long cell_index,
int cell_id = unique_cell_ids[cell_index];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
int col_index;
if (cell &&
cell->GetIntAttribute(
@@ -1226,7 +1228,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long cell_index,
}
STDMETHODIMP BrowserAccessibilityWin::get_nColumns(long* column_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!column_count)
@@ -1243,7 +1245,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nColumns(long* column_count) {
}
STDMETHODIMP BrowserAccessibilityWin::get_nRows(long* row_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row_count)
@@ -1259,7 +1261,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nRows(long* row_count) {
}
STDMETHODIMP BrowserAccessibilityWin::get_nSelectedChildren(long* cell_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!cell_count)
@@ -1271,7 +1273,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelectedChildren(long* cell_count) {
}
STDMETHODIMP BrowserAccessibilityWin::get_nSelectedColumns(long* column_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!column_count)
@@ -1282,7 +1284,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelectedColumns(long* column_count) {
}
STDMETHODIMP BrowserAccessibilityWin::get_nSelectedRows(long* row_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row_count)
@@ -1294,7 +1296,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelectedRows(long* row_count) {
STDMETHODIMP BrowserAccessibilityWin::get_rowDescription(long row,
BSTR* description) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!description)
@@ -1318,9 +1320,9 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowDescription(long row,
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids[row * columns + i];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
- if (cell && cell->role_ == blink::WebAXRoleRowHeader) {
- string16 cell_name = cell->GetString16Attribute(
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ if (cell && cell->blink_role() == blink::WebAXRoleRowHeader) {
+ base::string16 cell_name = cell->GetString16Attribute(
AccessibilityNodeData::ATTR_NAME);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
@@ -1338,7 +1340,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowDescription(long row,
STDMETHODIMP BrowserAccessibilityWin::get_rowExtentAt(long row,
long column,
long* n_rows_spanned) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_rows_spanned)
@@ -1361,7 +1363,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowExtentAt(long row,
AccessibilityNodeData::ATTR_CELL_IDS);
int cell_id = cell_ids[row * columns + column];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
int rowspan;
if (cell &&
cell->GetIntAttribute(
@@ -1383,7 +1385,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeader(
STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long cell_index,
long* row_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row_index)
@@ -1399,7 +1401,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long cell_index,
int cell_id = unique_cell_ids[cell_index];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
int cell_row_index;
if (cell &&
cell->GetIntAttribute(
@@ -1414,7 +1416,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long cell_index,
STDMETHODIMP BrowserAccessibilityWin::get_selectedChildren(long max_children,
long** children,
long* n_children) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!children || !n_children)
@@ -1428,7 +1430,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedChildren(long max_children,
STDMETHODIMP BrowserAccessibilityWin::get_selectedColumns(long max_columns,
long** columns,
long* n_columns) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!columns || !n_columns)
@@ -1442,7 +1444,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedColumns(long max_columns,
STDMETHODIMP BrowserAccessibilityWin::get_selectedRows(long max_rows,
long** rows,
long* n_rows) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!rows || !n_rows)
@@ -1454,7 +1456,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedRows(long max_rows,
}
STDMETHODIMP BrowserAccessibilityWin::get_summary(IUnknown** accessible) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!accessible)
@@ -1467,7 +1469,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_summary(IUnknown** accessible) {
STDMETHODIMP BrowserAccessibilityWin::get_isColumnSelected(
long column,
boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!is_selected)
@@ -1480,7 +1482,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_isColumnSelected(
STDMETHODIMP BrowserAccessibilityWin::get_isRowSelected(long row,
boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!is_selected)
@@ -1494,7 +1496,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_isRowSelected(long row,
STDMETHODIMP BrowserAccessibilityWin::get_isSelected(long row,
long column,
boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!is_selected)
@@ -1512,7 +1514,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtentsAtIndex(
long* row_extents,
long* column_extents,
boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row || !column || !row_extents || !column_extents || !is_selected)
@@ -1528,7 +1530,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtentsAtIndex(
int cell_id = unique_cell_ids[index];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
int rowspan;
int colspan;
if (cell &&
@@ -1563,7 +1565,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelectedCells(long* cell_count) {
STDMETHODIMP BrowserAccessibilityWin::get_selectedCells(
IUnknown*** cells,
long* n_selected_cells) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!cells || !n_selected_cells)
@@ -1576,7 +1578,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedCells(
STDMETHODIMP BrowserAccessibilityWin::get_selectedColumns(long** columns,
long* n_columns) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!columns || !n_columns)
@@ -1589,7 +1591,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedColumns(long** columns,
STDMETHODIMP BrowserAccessibilityWin::get_selectedRows(long** rows,
long* n_rows) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!rows || !n_rows)
@@ -1607,7 +1609,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_selectedRows(long** rows,
STDMETHODIMP BrowserAccessibilityWin::get_columnExtent(
long* n_columns_spanned) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_columns_spanned)
@@ -1627,7 +1629,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnExtent(
STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
IUnknown*** cell_accessibles,
long* n_column_header_cells) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!cell_accessibles || !n_column_header_cells)
@@ -1666,8 +1668,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids[i * columns + column];
BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
- if (cell && cell->role_ == blink::WebAXRoleColumnHeader)
+ manager()->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
+ if (cell && cell->blink_role() == blink::WebAXRoleColumnHeader)
(*n_column_header_cells)++;
}
@@ -1676,11 +1678,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
int index = 0;
for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids[i * columns + column];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
- if (cell && cell->role_ == blink::WebAXRoleColumnHeader) {
- (*cell_accessibles)[index] =
- static_cast<IAccessible*>(cell->NewReference());
+ BrowserAccessibility* cell = manager()->GetFromRendererID(cell_id);
+ if (cell && cell->role() == blink::WebAXRoleColumnHeader) {
+ (*cell_accessibles)[index] = static_cast<IAccessible*>(
+ cell->ToBrowserAccessibilityWin()->NewReference());
++index;
}
}
@@ -1689,7 +1690,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
}
STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long* column_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!column_index)
@@ -1706,7 +1707,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(long* column_index) {
}
STDMETHODIMP BrowserAccessibilityWin::get_rowExtent(long* n_rows_spanned) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_rows_spanned)
@@ -1726,7 +1727,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowExtent(long* n_rows_spanned) {
STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
IUnknown*** cell_accessibles,
long* n_row_header_cells) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!cell_accessibles || !n_row_header_cells)
@@ -1764,9 +1765,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids[row * columns + i];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
- if (cell && cell->role_ == blink::WebAXRoleRowHeader)
+ BrowserAccessibility* cell = manager()->GetFromRendererID(cell_id);
+ if (cell && cell->role() == blink::WebAXRoleRowHeader)
(*n_row_header_cells)++;
}
@@ -1775,11 +1775,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
int index = 0;
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids[row * columns + i];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->ToBrowserAccessibilityWin();
- if (cell && cell->role_ == blink::WebAXRoleRowHeader) {
- (*cell_accessibles)[index] =
- static_cast<IAccessible*>(cell->NewReference());
+ BrowserAccessibility* cell = manager()->GetFromRendererID(cell_id);
+ if (cell && cell->role() == blink::WebAXRoleRowHeader) {
+ (*cell_accessibles)[index] = static_cast<IAccessible*>(
+ cell->ToBrowserAccessibilityWin()->NewReference());
++index;
}
}
@@ -1788,7 +1787,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
}
STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long* row_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row_index)
@@ -1803,7 +1802,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(long* row_index) {
}
STDMETHODIMP BrowserAccessibilityWin::get_isSelected(boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!is_selected)
@@ -1819,7 +1818,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtents(
long* row_extents,
long* column_extents,
boolean* is_selected) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!row_index ||
@@ -1853,7 +1852,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtents(
}
STDMETHODIMP BrowserAccessibilityWin::get_table(IUnknown** table) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!table)
@@ -1884,7 +1883,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_table(IUnknown** table) {
//
STDMETHODIMP BrowserAccessibilityWin::get_nCharacters(LONG* n_characters) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_characters)
@@ -1895,15 +1894,15 @@ STDMETHODIMP BrowserAccessibilityWin::get_nCharacters(LONG* n_characters) {
}
STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!offset)
return E_INVALIDARG;
*offset = 0;
- if (role_ == blink::WebAXRoleTextField ||
- role_ == blink::WebAXRoleTextArea) {
+ if (blink_role() == blink::WebAXRoleTextField ||
+ blink_role() == blink::WebAXRoleTextArea) {
int sel_start = 0;
if (GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_START,
&sel_start))
@@ -1920,18 +1919,21 @@ STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
LONG* out_y,
LONG* out_width,
LONG* out_height) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!out_x || !out_y || !out_width || !out_height)
return E_INVALIDARG;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
HandleSpecialTextOffset(text_str, &offset);
if (offset < 0 || offset > static_cast<LONG>(text_str.size()))
return E_INVALIDARG;
+ if (blink_role() != blink::WebAXRoleStaticText)
+ return E_FAIL;
+
gfx::Rect character_bounds;
if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
character_bounds = GetGlobalBoundsForRange(offset, 1);
@@ -1951,15 +1953,15 @@ STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
}
STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!n_selections)
return E_INVALIDARG;
*n_selections = 0;
- if (role_ == blink::WebAXRoleTextField ||
- role_ == blink::WebAXRoleTextArea) {
+ if (blink_role() == blink::WebAXRoleTextField ||
+ blink_role() == blink::WebAXRoleTextArea) {
int sel_start = 0;
int sel_end = 0;
if (GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_START,
@@ -1975,7 +1977,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
LONG* start_offset,
LONG* end_offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!start_offset || !end_offset || selection_index != 0)
@@ -1983,8 +1985,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
*start_offset = 0;
*end_offset = 0;
- if (role_ == blink::WebAXRoleTextField ||
- role_ == blink::WebAXRoleTextArea) {
+ if (blink_role() == blink::WebAXRoleTextField ||
+ blink_role() == blink::WebAXRoleTextArea) {
int sel_start = 0;
int sel_end = 0;
if (GetIntAttribute(
@@ -2001,13 +2003,13 @@ STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
LONG end_offset,
BSTR* text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!text)
return E_INVALIDARG;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
// Handle special text offsets.
HandleSpecialTextOffset(text_str, &start_offset);
@@ -2028,7 +2030,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
if (end_offset > len)
return E_INVALIDARG;
- string16 substr = text_str.substr(start_offset, end_offset - start_offset);
+ base::string16 substr = text_str.substr(start_offset,
+ end_offset - start_offset);
if (substr.empty())
return S_FALSE;
@@ -2043,7 +2046,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!start_offset || !end_offset || !text)
@@ -2058,7 +2061,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
return S_FALSE;
}
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
*start_offset = FindBoundary(
text_str, boundary_type, offset, ui::BACKWARDS_DIRECTION);
@@ -2073,7 +2076,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!start_offset || !end_offset || !text)
@@ -2088,7 +2091,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
return S_FALSE;
}
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
*start_offset = FindBoundary(
text_str, boundary_type, offset, ui::BACKWARDS_DIRECTION);
@@ -2102,7 +2105,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
LONG* start_offset,
LONG* end_offset,
BSTR* text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!start_offset || !end_offset || !text)
@@ -2117,7 +2120,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
return S_FALSE;
}
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
*start_offset = offset;
*end_offset = FindBoundary(
@@ -2126,13 +2129,13 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
}
STDMETHODIMP BrowserAccessibilityWin::get_newText(IA2TextSegment* new_text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!new_text)
return E_INVALIDARG;
- string16 text = TextForIAccessibleText();
+ base::string16 text = TextForIAccessibleText();
new_text->text = SysAllocString(text.c_str());
new_text->start = 0;
@@ -2141,7 +2144,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_newText(IA2TextSegment* new_text) {
}
STDMETHODIMP BrowserAccessibilityWin::get_oldText(IA2TextSegment* old_text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!old_text)
@@ -2158,7 +2161,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_offsetAtPoint(
LONG y,
enum IA2CoordinateType coord_type,
LONG* offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!offset)
@@ -2190,52 +2193,52 @@ STDMETHODIMP BrowserAccessibilityWin::scrollSubstringToPoint(
STDMETHODIMP BrowserAccessibilityWin::addSelection(LONG start_offset,
LONG end_offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
HandleSpecialTextOffset(text_str, &start_offset);
HandleSpecialTextOffset(text_str, &end_offset);
- manager_->SetTextSelection(*this, start_offset, end_offset);
+ manager()->SetTextSelection(*this, start_offset, end_offset);
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::removeSelection(LONG selection_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (selection_index != 0)
return E_INVALIDARG;
- manager_->SetTextSelection(*this, 0, 0);
+ manager()->SetTextSelection(*this, 0, 0);
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::setCaretOffset(LONG offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
HandleSpecialTextOffset(text_str, &offset);
- manager_->SetTextSelection(*this, offset, offset);
+ manager()->SetTextSelection(*this, offset, offset);
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::setSelection(LONG selection_index,
LONG start_offset,
LONG end_offset) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (selection_index != 0)
return E_INVALIDARG;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
HandleSpecialTextOffset(text_str, &start_offset);
HandleSpecialTextOffset(text_str, &end_offset);
- manager_->SetTextSelection(*this, start_offset, end_offset);
+ manager()->SetTextSelection(*this, start_offset, end_offset);
return S_OK;
}
@@ -2244,7 +2247,7 @@ STDMETHODIMP BrowserAccessibilityWin::setSelection(LONG selection_index,
//
STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!hyperlink_count)
@@ -2257,7 +2260,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) {
STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
long index,
IAccessibleHyperlink** hyperlink) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!hyperlink ||
@@ -2267,7 +2270,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
}
BrowserAccessibilityWin* child =
- children_[hyperlinks_[index]]->ToBrowserAccessibilityWin();
+ children()[hyperlinks_[index]]->ToBrowserAccessibilityWin();
*hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference());
return S_OK;
}
@@ -2275,7 +2278,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
long char_index,
long* hyperlink_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!hyperlink_index)
@@ -2300,7 +2303,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
//
STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!value)
@@ -2319,7 +2322,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) {
}
STDMETHODIMP BrowserAccessibilityWin::get_minimumValue(VARIANT* value) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!value)
@@ -2338,7 +2341,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_minimumValue(VARIANT* value) {
}
STDMETHODIMP BrowserAccessibilityWin::get_maximumValue(VARIANT* value) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!value)
@@ -2366,7 +2369,7 @@ STDMETHODIMP BrowserAccessibilityWin::setCurrentValue(VARIANT new_value) {
//
STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!url)
@@ -2376,7 +2379,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) {
}
STDMETHODIMP BrowserAccessibilityWin::get_title(BSTR* title) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!title)
@@ -2386,7 +2389,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_title(BSTR* title) {
}
STDMETHODIMP BrowserAccessibilityWin::get_mimeType(BSTR* mime_type) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!mime_type)
@@ -2397,7 +2400,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_mimeType(BSTR* mime_type) {
}
STDMETHODIMP BrowserAccessibilityWin::get_docType(BSTR* doc_type) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!doc_type)
@@ -2418,7 +2421,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nodeInfo(
unsigned int* num_children,
unsigned int* unique_id,
unsigned short* node_type) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node_name || !name_space_id || !node_value || !num_children ||
@@ -2426,14 +2429,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_nodeInfo(
return E_INVALIDARG;
}
- string16 tag;
+ base::string16 tag;
if (GetString16Attribute(AccessibilityNodeData::ATTR_HTML_TAG, &tag))
*node_name = SysAllocString(tag.c_str());
else
*node_name = NULL;
*name_space_id = 0;
- *node_value = SysAllocString(UTF8ToUTF16(value_).c_str());
+ *node_value = SysAllocString(UTF8ToUTF16(value()).c_str());
*num_children = PlatformChildCount();
*unique_id = unique_id_win_;
@@ -2455,22 +2458,22 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributes(
short* name_space_id,
BSTR* attrib_values,
unsigned short* num_attribs) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!attrib_names || !name_space_id || !attrib_values || !num_attribs)
return E_INVALIDARG;
*num_attribs = max_attribs;
- if (*num_attribs > html_attributes_.size())
- *num_attribs = html_attributes_.size();
+ if (*num_attribs > html_attributes().size())
+ *num_attribs = html_attributes().size();
for (unsigned short i = 0; i < *num_attribs; ++i) {
attrib_names[i] = SysAllocString(
- UTF8ToUTF16(html_attributes_[i].first).c_str());
+ UTF8ToUTF16(html_attributes()[i].first).c_str());
name_space_id[i] = 0;
attrib_values[i] = SysAllocString(
- UTF8ToUTF16(html_attributes_[i].second).c_str());
+ UTF8ToUTF16(html_attributes()[i].second).c_str());
}
return S_OK;
}
@@ -2480,7 +2483,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributesForNames(
BSTR* attrib_names,
short* name_space_id,
BSTR* attrib_values) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!attrib_names || !name_space_id || !attrib_values)
@@ -2490,10 +2493,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributesForNames(
name_space_id[i] = 0;
bool found = false;
std::string name = UTF16ToUTF8((LPCWSTR)attrib_names[i]);
- for (unsigned int j = 0; j < html_attributes_.size(); ++j) {
- if (html_attributes_[j].first == name) {
+ for (unsigned int j = 0; j < html_attributes().size(); ++j) {
+ if (html_attributes()[j].first == name) {
attrib_values[i] = SysAllocString(
- UTF8ToUTF16(html_attributes_[j].second).c_str());
+ UTF8ToUTF16(html_attributes()[j].second).c_str());
found = true;
break;
}
@@ -2511,7 +2514,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_computedStyle(
BSTR* style_properties,
BSTR* style_values,
unsigned short *num_style_properties) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!style_properties || !style_values)
@@ -2519,7 +2522,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_computedStyle(
// We only cache a single style property for now: DISPLAY
- string16 display;
+ base::string16 display;
if (max_style_properties == 0 ||
!GetString16Attribute(AccessibilityNodeData::ATTR_DISPLAY, &display)) {
*num_style_properties = 0;
@@ -2538,7 +2541,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_computedStyleForProperties(
boolean use_alternate_view,
BSTR* style_properties,
BSTR* style_values) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!style_properties || !style_values)
@@ -2547,10 +2550,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_computedStyleForProperties(
// We only cache a single style property for now: DISPLAY
for (unsigned short i = 0; i < num_style_properties; ++i) {
- string16 name = (LPCWSTR)style_properties[i];
+ base::string16 name = (LPCWSTR)style_properties[i];
StringToLowerASCII(&name);
if (name == L"display") {
- string16 display = GetString16Attribute(
+ base::string16 display = GetString16Attribute(
AccessibilityNodeData::ATTR_DISPLAY);
style_values[i] = SysAllocString(display.c_str());
} else {
@@ -2567,18 +2570,18 @@ STDMETHODIMP BrowserAccessibilityWin::scrollTo(boolean placeTopLeft) {
}
STDMETHODIMP BrowserAccessibilityWin::get_parentNode(ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
return E_INVALIDARG;
- *node = parent_->ToBrowserAccessibilityWin()->NewReference();
+ *node = parent()->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_firstChild(ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
@@ -2594,7 +2597,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_firstChild(ISimpleDOMNode** node) {
}
STDMETHODIMP BrowserAccessibilityWin::get_lastChild(ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
@@ -2612,37 +2615,37 @@ STDMETHODIMP BrowserAccessibilityWin::get_lastChild(ISimpleDOMNode** node) {
STDMETHODIMP BrowserAccessibilityWin::get_previousSibling(
ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
return E_INVALIDARG;
- if (!parent_ || index_in_parent_ <= 0) {
+ if (!parent() || index_in_parent() <= 0) {
*node = NULL;
return S_FALSE;
}
- *node = parent_->children()[index_in_parent_ - 1]->
+ *node = parent()->children()[index_in_parent() - 1]->
ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
STDMETHODIMP BrowserAccessibilityWin::get_nextSibling(ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
return E_INVALIDARG;
- if (!parent_ ||
- index_in_parent_ < 0 ||
- index_in_parent_ >= static_cast<int>(parent_->children().size()) - 1) {
+ if (!parent() ||
+ index_in_parent() < 0 ||
+ index_in_parent() >= static_cast<int>(parent()->children().size()) - 1) {
*node = NULL;
return S_FALSE;
}
- *node = parent_->children()[index_in_parent_ + 1]->
+ *node = parent()->children()[index_in_parent() + 1]->
ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
@@ -2650,7 +2653,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nextSibling(ISimpleDOMNode** node) {
STDMETHODIMP BrowserAccessibilityWin::get_childAt(
unsigned int child_index,
ISimpleDOMNode** node) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!node)
@@ -2674,7 +2677,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_childAt(
//
STDMETHODIMP BrowserAccessibilityWin::get_domText(BSTR* dom_text) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!dom_text)
@@ -2704,19 +2707,22 @@ STDMETHODIMP BrowserAccessibilityWin::get_unclippedSubstringBounds(
int* out_y,
int* out_width,
int* out_height) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
if (!out_x || !out_y || !out_width || !out_height)
return E_INVALIDARG;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
if (start_index > text_str.size() ||
end_index > text_str.size() ||
start_index > end_index) {
return E_INVALIDARG;
}
+ if (blink_role() != blink::WebAXRoleStaticText)
+ return E_FAIL;
+
gfx::Rect bounds = GetGlobalBoundsForRange(
start_index, end_index - start_index);
*out_x = bounds.x();
@@ -2729,19 +2735,19 @@ STDMETHODIMP BrowserAccessibilityWin::get_unclippedSubstringBounds(
STDMETHODIMP BrowserAccessibilityWin::scrollToSubstring(
unsigned int start_index,
unsigned int end_index) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
- const string16& text_str = TextForIAccessibleText();
+ const base::string16& text_str = TextForIAccessibleText();
if (start_index > text_str.size() ||
end_index > text_str.size() ||
start_index > end_index) {
return E_INVALIDARG;
}
- manager_->ScrollToMakeVisible(*this, GetLocalBoundsForRange(
+ manager()->ScrollToMakeVisible(*this, GetLocalBoundsForRange(
start_index, end_index - start_index));
- manager_->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
+ manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this);
return S_OK;
}
@@ -2753,7 +2759,7 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToSubstring(
STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guidService,
REFIID riid,
void** object) {
- if (!instance_active_)
+ if (!instance_active())
return E_FAIL;
// The system uses IAccessible APIs for many purposes, but only
@@ -2766,7 +2772,7 @@ STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guidService,
// Special Mozilla extension: return the accessible for the root document.
// Screen readers use this to distinguish between a document loaded event
// on the root document vs on an iframe.
- return manager_->GetRoot()->ToBrowserAccessibilityWin()->QueryInterface(
+ return manager()->GetRoot()->ToBrowserAccessibilityWin()->QueryInterface(
IID_IAccessible2, object);
}
@@ -2812,7 +2818,7 @@ STDMETHODIMP BrowserAccessibilityWin::GetPatternProvider(PATTERNID id,
if (IsEditableText()) {
// The BrowserAccessibilityManager keeps track of instances when
// we don't want to show the on-screen keyboard.
- if (!manager_->IsOSKAllowed(GetGlobalBoundsRect()))
+ if (!manager()->IsOSKAllowed(GetGlobalBoundsRect()))
return E_NOTIMPL;
DVLOG(1) << "Returning UIA text provider";
@@ -2903,13 +2909,13 @@ void BrowserAccessibilityWin::PreInitialize() {
IntAttributeToIA2(AccessibilityNodeData::ATTR_HIERARCHICAL_LEVEL, "level");
// Expose the set size and position in set for listbox options.
- if (role_ == blink::WebAXRoleListBoxOption &&
- parent_ &&
- parent_->role() == blink::WebAXRoleListBox) {
+ if (blink_role() == blink::WebAXRoleListBoxOption &&
+ parent() &&
+ parent()->role() == blink::WebAXRoleListBox) {
ia2_attributes_.push_back(
- L"setsize:" + base::IntToString16(parent_->PlatformChildCount()));
+ L"setsize:" + base::IntToString16(parent()->PlatformChildCount()));
ia2_attributes_.push_back(
- L"setsize:" + base::IntToString16(index_in_parent_ + 1));
+ L"setsize:" + base::IntToString16(index_in_parent() + 1));
}
if (ia_role_ == ROLE_SYSTEM_CHECKBUTTON ||
@@ -2950,9 +2956,9 @@ void BrowserAccessibilityWin::PreInitialize() {
const std::vector<int32>& unique_cell_ids = table->GetIntListAttribute(
AccessibilityNodeData::ATTR_UNIQUE_CELL_IDS);
for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
- if (unique_cell_ids[i] == renderer_id_) {
+ if (unique_cell_ids[i] == renderer_id()) {
ia2_attributes_.push_back(
- string16(L"table-cell-index:") + base::IntToString16(i));
+ base::string16(L"table-cell-index:") + base::IntToString16(i));
}
}
}
@@ -3000,25 +3006,25 @@ void BrowserAccessibilityWin::PreInitialize() {
// it's nonempty, and the help should become the description if
// there's no description - or the name if there's no name or description.
if (!description.empty()) {
- name_ = description;
+ set_name(description);
description.clear();
}
if (!help.empty() && description.empty()) {
description = help;
help.clear();
}
- if (!description.empty() && name_.empty() && !title_elem_id) {
- name_ = description;
+ if (!description.empty() && name().empty() && !title_elem_id) {
+ set_name(description);
description.clear();
}
// If it's a text field, also consider the placeholder.
std::string placeholder;
- if (role_ == blink::WebAXRoleTextField &&
+ if (blink_role() == blink::WebAXRoleTextField &&
HasState(blink::WebAXStateFocusable) &&
GetHtmlAttribute("placeholder", &placeholder)) {
- if (name_.empty() && !title_elem_id) {
- name_ = placeholder;
+ if (name().empty() && !title_elem_id) {
+ set_name(placeholder);
} else if (description.empty()) {
description = placeholder;
}
@@ -3028,25 +3034,27 @@ void BrowserAccessibilityWin::PreInitialize() {
SetStringAttribute(AccessibilityNodeData::ATTR_HELP, help);
// On Windows, the value of a document should be its url.
- if (role_ == blink::WebAXRoleRootWebArea ||
- role_ == blink::WebAXRoleWebArea) {
- GetStringAttribute(AccessibilityNodeData::ATTR_DOC_URL, &value_);
+ if (blink_role() == blink::WebAXRoleRootWebArea ||
+ blink_role() == blink::WebAXRoleWebArea) {
+ set_value(GetStringAttribute(AccessibilityNodeData::ATTR_DOC_URL));
}
// For certain roles (listbox option, static text, and list marker)
// WebKit stores the main accessible text in the "value" - swap it so
// that it's the "name".
- if (name_.empty() &&
- (role_ == blink::WebAXRoleListBoxOption ||
- role_ == blink::WebAXRoleStaticText ||
- role_ == blink::WebAXRoleListMarker)) {
- name_.swap(value_);
+ if (name().empty() &&
+ (blink_role() == blink::WebAXRoleListBoxOption ||
+ blink_role() == blink::WebAXRoleStaticText ||
+ blink_role() == blink::WebAXRoleListMarker)) {
+ std::string tmp = value();
+ set_value(name());
+ set_name(tmp);
}
// If this doesn't have a value and is linked then set its value to the url
// attribute. This allows screen readers to read an empty link's destination.
- if (value_.empty() && (ia_state_ & STATE_SYSTEM_LINKED))
- GetStringAttribute(AccessibilityNodeData::ATTR_URL, &value_);
+ if (value().empty() && (ia_state_ & STATE_SYSTEM_LINKED))
+ set_value(GetStringAttribute(AccessibilityNodeData::ATTR_URL));
// Clear any old relationships between this node and other nodes.
for (size_t i = 0; i < relations_.size(); ++i)
@@ -3087,14 +3095,14 @@ void BrowserAccessibilityWin::PostInitialize() {
DCHECK_EQ(hyperlink_offset_to_index_.size(), hyperlinks_.size());
// Fire an event when an alert first appears.
- if (role_ == blink::WebAXRoleAlert && first_time_)
- manager_->NotifyAccessibilityEvent(blink::WebAXEventAlert, this);
+ if (blink_role() == blink::WebAXRoleAlert && first_time_)
+ manager()->NotifyAccessibilityEvent(blink::WebAXEventAlert, this);
// Fire events if text has changed.
- string16 text = TextForIAccessibleText();
+ base::string16 text = TextForIAccessibleText();
if (previous_text_ != text) {
if (!previous_text_.empty() && !text.empty()) {
- manager_->NotifyAccessibilityEvent(
+ manager()->NotifyAccessibilityEvent(
blink::WebAXEventShow, this);
}
@@ -3107,13 +3115,13 @@ void BrowserAccessibilityWin::PostInitialize() {
// Fire events if the state has changed.
if (!first_time_ && ia_state_ != old_ia_state_) {
BrowserAccessibilityManagerWin* manager =
- manager_->ToBrowserAccessibilityManagerWin();
+ this->manager()->ToBrowserAccessibilityManagerWin();
// Normally focus events are handled elsewhere, however
// focus for managed descendants is platform-specific.
// Fire a focus event if the focused descendant in a multi-select
// list box changes.
- if (role_ == blink::WebAXRoleListBoxOption &&
+ if (blink_role() == blink::WebAXRoleListBoxOption &&
(ia_state_ & STATE_SYSTEM_FOCUSABLE) &&
(ia_state_ & STATE_SYSTEM_SELECTABLE) &&
(ia_state_ & STATE_SYSTEM_FOCUSED) &&
@@ -3151,7 +3159,7 @@ bool BrowserAccessibilityWin::IsNative() const {
void BrowserAccessibilityWin::SetLocation(const gfx::Rect& new_location) {
BrowserAccessibility::SetLocation(new_location);
- manager_->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent(
+ manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent(
EVENT_OBJECT_LOCATIONCHANGE, unique_id_win());
}
@@ -3172,14 +3180,14 @@ BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID(
if (child_id >= 1 && child_id <= static_cast<LONG>(PlatformChildCount()))
return PlatformGetChild(child_id - 1)->ToBrowserAccessibilityWin();
- return manager_->ToBrowserAccessibilityManagerWin()->
+ return manager()->ToBrowserAccessibilityManagerWin()->
GetFromUniqueIdWin(child_id);
}
HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr(
AccessibilityNodeData::StringAttribute attribute,
BSTR* value_bstr) {
- string16 str;
+ base::string16 str;
if (!GetString16Attribute(attribute, &str))
return S_FALSE;
@@ -3196,7 +3204,7 @@ HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr(
void BrowserAccessibilityWin::StringAttributeToIA2(
AccessibilityNodeData::StringAttribute attribute,
const char* ia2_attr) {
- string16 value;
+ base::string16 value;
if (GetString16Attribute(attribute, &value))
ia2_attributes_.push_back(ASCIIToUTF16(ia2_attr) + L":" + value);
}
@@ -3221,9 +3229,10 @@ void BrowserAccessibilityWin::IntAttributeToIA2(
}
}
-string16 BrowserAccessibilityWin::GetValueText() {
+base::string16 BrowserAccessibilityWin::GetValueText() {
float fval;
- string16 value = UTF8ToUTF16(value_);
+ base::string16 value = UTF8ToUTF16(this->value());
+
if (value.empty() &&
GetFloatAttribute(AccessibilityNodeData::ATTR_VALUE_FOR_RANGE, &fval)) {
value = UTF8ToUTF16(base::DoubleToString(fval));
@@ -3231,15 +3240,16 @@ string16 BrowserAccessibilityWin::GetValueText() {
return value;
}
-string16 BrowserAccessibilityWin::TextForIAccessibleText() {
+base::string16 BrowserAccessibilityWin::TextForIAccessibleText() {
if (IsEditableText())
- return UTF8ToUTF16(value_);
- return (role_ == blink::WebAXRoleStaticText) ?
- UTF8ToUTF16(name_) : hypertext_;
+ return UTF8ToUTF16(value());
+ return (blink_role() == blink::WebAXRoleStaticText) ?
+ UTF8ToUTF16(name()) : hypertext_;
}
-void BrowserAccessibilityWin::HandleSpecialTextOffset(const string16& text,
- LONG* offset) {
+void BrowserAccessibilityWin::HandleSpecialTextOffset(
+ const base::string16& text,
+ LONG* offset) {
if (*offset == IA2_TEXT_OFFSET_LENGTH)
*offset = static_cast<LONG>(text.size());
else if (*offset == IA2_TEXT_OFFSET_CARET)
@@ -3262,7 +3272,7 @@ ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary(
}
LONG BrowserAccessibilityWin::FindBoundary(
- const string16& text,
+ const base::string16& text,
IA2TextBoundaryType ia2_boundary,
LONG start_offset,
ui::TextBoundaryDirection direction) {
@@ -3276,7 +3286,7 @@ LONG BrowserAccessibilityWin::FindBoundary(
BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromRendererID(
int32 renderer_id) {
- return manager_->GetFromRendererID(renderer_id)->ToBrowserAccessibilityWin();
+ return manager()->GetFromRendererID(renderer_id)->ToBrowserAccessibilityWin();
}
void BrowserAccessibilityWin::InitRoleAndState() {
@@ -3339,7 +3349,7 @@ void BrowserAccessibilityWin::InitRoleAndState() {
if (!HasState(blink::WebAXStateReadonly))
ia2_state_ |= IA2_STATE_EDITABLE;
- string16 invalid;
+ base::string16 invalid;
if (GetHtmlAttribute("aria-invalid", &invalid))
ia2_state_ |= IA2_STATE_INVALID_ENTRY;
@@ -3349,11 +3359,11 @@ void BrowserAccessibilityWin::InitRoleAndState() {
if (GetBoolAttribute(AccessibilityNodeData::ATTR_CAN_SET_VALUE))
ia2_state_ |= IA2_STATE_EDITABLE;
- string16 html_tag = GetString16Attribute(
+ base::string16 html_tag = GetString16Attribute(
AccessibilityNodeData::ATTR_HTML_TAG);
ia_role_ = 0;
ia2_role_ = 0;
- switch (role_) {
+ switch (blink_role()) {
case blink::WebAXRoleAlert:
ia_role_ = ROLE_SYSTEM_ALERT;
break;
@@ -3463,7 +3473,7 @@ void BrowserAccessibilityWin::InitRoleAndState() {
ia_state_ |= STATE_SYSTEM_READONLY;
break;
case blink::WebAXRoleGroup: {
- string16 aria_role = GetString16Attribute(
+ base::string16 aria_role = GetString16Attribute(
AccessibilityNodeData::ATTR_ROLE);
if (aria_role == L"group" || html_tag == L"fieldset") {
ia_role_ = ROLE_SYSTEM_GROUPING;
@@ -3661,7 +3671,7 @@ void BrowserAccessibilityWin::InitRoleAndState() {
ia_role_ = ROLE_SYSTEM_PAGETAB;
break;
case blink::WebAXRoleTable: {
- string16 aria_role = GetString16Attribute(
+ base::string16 aria_role = GetString16Attribute(
AccessibilityNodeData::ATTR_ROLE);
if (aria_role == L"treegrid") {
ia_role_ = ROLE_SYSTEM_OUTLINE;
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h
index 1bb6ee20d7..a1a3624733 100644
--- a/content/browser/accessibility/browser_accessibility_win.h
+++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -86,8 +86,8 @@ BrowserAccessibilityWin
// Mappings from roles and states to human readable strings. Initialize
// with |InitializeStringMaps|.
- static std::map<int32, string16> role_string_map;
- static std::map<int32, string16> state_string_map;
+ static std::map<int32, base::string16> role_string_map;
+ static std::map<int32, base::string16> state_string_map;
CONTENT_EXPORT BrowserAccessibilityWin();
@@ -765,13 +765,17 @@ BrowserAccessibilityWin
// Accessors.
int32 ia_role() const { return ia_role_; }
int32 ia_state() const { return ia_state_; }
- const string16& role_name() const { return role_name_; }
+ const base::string16& role_name() const { return role_name_; }
int32 ia2_role() const { return ia2_role_; }
int32 ia2_state() const { return ia2_state_; }
- const std::vector<string16>& ia2_attributes() const {
+ const std::vector<base::string16>& ia2_attributes() const {
return ia2_attributes_;
}
+ // BrowserAccessibility::role is shadowed by IAccessible2::role, so
+ // we provide an alias for it.
+ int32 blink_role() const { return BrowserAccessibility::role(); }
+
private:
// Add one to the reference count and return the same object. Always
// use this method when returning a BrowserAccessibilityWin object as
@@ -813,15 +817,15 @@ BrowserAccessibilityWin
// Get the value text, which might come from the floating-point
// value for some roles.
- string16 GetValueText();
+ base::string16 GetValueText();
// Get the text of this node for the purposes of IAccessibleText - it may
// be the name, it may be the value, etc. depending on the role.
- string16 TextForIAccessibleText();
+ base::string16 TextForIAccessibleText();
// If offset is a member of IA2TextSpecialOffsets this function updates the
// value of offset and returns, otherwise offset remains unchanged.
- void HandleSpecialTextOffset(const string16& text, LONG* offset);
+ void HandleSpecialTextOffset(const base::string16& text, LONG* offset);
// Convert from a IA2TextBoundaryType to a ui::TextBoundaryType.
ui::TextBoundaryType IA2TextBoundaryToTextBoundary(IA2TextBoundaryType type);
@@ -829,7 +833,7 @@ BrowserAccessibilityWin
// Search forwards (direction == 1) or backwards (direction == -1)
// from the given offset until the given boundary is found, and
// return the offset of that boundary.
- LONG FindBoundary(const string16& text,
+ LONG FindBoundary(const base::string16& text,
IA2TextBoundaryType ia2_boundary,
LONG start_offset,
ui::TextBoundaryDirection direction);
@@ -846,26 +850,26 @@ BrowserAccessibilityWin
// IAccessible role and state.
int32 ia_role_;
int32 ia_state_;
- string16 role_name_;
+ base::string16 role_name_;
// IAccessible2 role and state.
int32 ia2_role_;
int32 ia2_state_;
// IAccessible2 attributes.
- std::vector<string16> ia2_attributes_;
+ std::vector<base::string16> ia2_attributes_;
// True in Initialize when the object is first created, and false
// subsequent times.
bool first_time_;
// The previous text, before the last update to this object.
- string16 previous_text_;
+ base::string16 previous_text_;
// The old text to return in IAccessibleText::get_oldText - this is like
// previous_text_ except that it's NOT updated when the object
// is initialized again but the text doesn't change.
- string16 old_text_;
+ base::string16 old_text_;
// The previous state, used to see if there was a state change.
int32 old_ia_state_;
@@ -874,7 +878,7 @@ BrowserAccessibilityWin
std::vector<BrowserAccessibilityRelation*> relations_;
// The text of this node including embedded hyperlink characters.
- string16 hypertext_;
+ base::string16 hypertext_;
// Maps the |hypertext_| embedded character offset to an index in
// |hyperlinks_|.
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index edb572f014..c1159e6eb6 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -219,7 +219,7 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
base::win::ScopedBstr name;
hr = text_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(S_OK, hr);
- EXPECT_EQ(L"old text", string16(name));
+ EXPECT_EQ(L"old text", base::string16(name));
name.Reset();
text_dispatch.Release();
@@ -250,7 +250,7 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
hr = text_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(S_OK, hr);
- EXPECT_EQ(L"new text", string16(name));
+ EXPECT_EQ(L"new text", base::string16(name));
text_dispatch.Release();
text_accessible.Release();
@@ -354,7 +354,7 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
base::win::ScopedBstr text;
ASSERT_EQ(S_OK, text1_obj->get_text(0, text1_len, text.Receive()));
- ASSERT_EQ(text1_value, base::UTF16ToUTF8(string16(text)));
+ ASSERT_EQ(text1_value, base::UTF16ToUTF8(base::string16(text)));
text.Reset();
ASSERT_EQ(S_OK, text1_obj->get_text(0, 4, text.Receive()));
@@ -452,7 +452,7 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
base::win::ScopedBstr text;
ASSERT_EQ(S_OK, root_obj->get_text(0, text_len, text.Receive()));
- EXPECT_EQ(text1_name + text2_name, base::UTF16ToUTF8(string16(text)));
+ EXPECT_EQ(text1_name + text2_name, base::UTF16ToUTF8(base::string16(text)));
long hyperlink_count;
ASSERT_EQ(S_OK, root_obj->get_nHyperlinks(&hyperlink_count));
@@ -548,7 +548,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
const std::string embed = base::UTF16ToUTF8(
BrowserAccessibilityWin::kEmbeddedCharacter);
EXPECT_EQ(text1_name + embed + text2_name + embed,
- UTF16ToUTF8(string16(text)));
+ UTF16ToUTF8(base::string16(text)));
text.Reset();
long hyperlink_count;
@@ -566,7 +566,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
hyperlink.QueryInterface<IAccessibleText>(hypertext.Receive()));
EXPECT_EQ(S_OK, hypertext->get_text(0, 3, text.Receive()));
EXPECT_STREQ(button1_text_name.c_str(),
- base::UTF16ToUTF8(string16(text)).c_str());
+ base::UTF16ToUTF8(base::string16(text)).c_str());
text.Reset();
hyperlink.Release();
hypertext.Release();
@@ -576,7 +576,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
hyperlink.QueryInterface<IAccessibleText>(hypertext.Receive()));
EXPECT_EQ(S_OK, hypertext->get_text(0, 4, text.Receive()));
EXPECT_STREQ(link1_text_name.c_str(),
- base::UTF16ToUTF8(string16(text)).c_str());
+ base::UTF16ToUTF8(base::string16(text)).c_str());
text.Reset();
hyperlink.Release();
hypertext.Release();
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 45bf951a0a..8cceea7bc5 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -161,7 +161,7 @@ void DumpAccessibilityTreeTest::RunTest(
// Tolerate Windows-style line endings (\r\n) in the expected file:
// normalize by deleting all \r from the file (if any) to leave only \n.
std::string expected_contents;
- RemoveChars(expected_contents_raw, "\r", &expected_contents);
+ base::RemoveChars(expected_contents_raw, "\r", &expected_contents);
if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) {
printf("Skipping this test on this platform.\n");
@@ -169,7 +169,7 @@ void DumpAccessibilityTreeTest::RunTest(
}
// Load the page.
- string16 html_contents16;
+ base::string16 html_contents16;
html_contents16 = UTF8ToUTF16(html_contents);
GURL url = GetTestUrl("accessibility",
html_file.BaseName().MaybeAsASCII().c_str());
@@ -191,7 +191,7 @@ void DumpAccessibilityTreeTest::RunTest(
formatter.SetFilters(filters);
// Perform a diff (or write the initial baseline).
- string16 actual_contents_utf16;
+ base::string16 actual_contents_utf16;
formatter.FormatAccessibilityTree(&actual_contents_utf16);
std::string actual_contents = UTF16ToUTF8(actual_contents_utf16);
std::vector<std::string> actual_lines, expected_lines;
@@ -411,6 +411,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunTest(FILE_PATH_LITERAL("input-text-name-calc.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputTypes) {
+ RunTest(FILE_PATH_LITERAL("input-types.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityLabel) {
RunTest(FILE_PATH_LITERAL("label.html"));
}
diff --git a/content/browser/android/OWNERS b/content/browser/android/OWNERS
index 6a8f307049..4fd5d774a7 100644
--- a/content/browser/android/OWNERS
+++ b/content/browser/android/OWNERS
@@ -1,5 +1,4 @@
bulach@chromium.org
-joth@chromium.org
sievers@chromium.org
skyostil@chromium.org
tedchoc@chromium.org
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 88c88010f3..be30869473 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -24,6 +24,7 @@
#include "content/browser/android/tracing_controller_android.h"
#include "content/browser/android/web_contents_observer_android.h"
#include "content/browser/device_orientation/data_fetcher_impl_android.h"
+#include "content/browser/frame_host/navigation_controller_android.h"
#include "content/browser/geolocation/location_api_adapter_android.h"
#include "content/browser/media/android/media_drm_credential_manager.h"
#include "content/browser/media/android/media_resource_getter_impl.h"
@@ -33,6 +34,7 @@
#include "content/browser/renderer_host/java/java_bound_object.h"
#include "content/browser/speech/speech_recognizer_impl_android.h"
#include "content/browser/vibration/vibration_provider_android.h"
+#include "content/browser/web_contents/web_contents_android.h"
using content::SurfaceTexturePeerBrowserImpl;
@@ -56,11 +58,13 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
{"InterstitialPageDelegateAndroid",
content::InterstitialPageDelegateAndroid::
RegisterInterstitialPageDelegateAndroid},
+ {"LoadUrlParams", content::RegisterLoadUrlParams},
{"MediaDrmCredentialManager",
content::MediaDrmCredentialManager::RegisterMediaDrmCredentialManager},
{"MediaResourceGetterImpl",
content::MediaResourceGetterImpl::RegisterMediaResourceGetter},
- {"LoadUrlParams", content::RegisterLoadUrlParams},
+ {"NavigationControllerAndroid",
+ content::NavigationControllerAndroid::Register},
{"PowerSaveBlock", content::RegisterPowerSaveBlocker},
{"RegisterImeAdapter", content::RegisterImeAdapter},
{"SpeechRecognizerImplAndroid",
@@ -70,6 +74,7 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
{"TouchPoint", content::RegisterTouchPoint},
{"TracingControllerAndroid", content::RegisterTracingControllerAndroid},
{"VibrationProvider", content::VibrationProviderAndroid::Register},
+ {"WebContentsAndroid", content::WebContentsAndroid::Register},
{"WebContentsObserverAndroid", content::RegisterWebContentsObserverAndroid},
{"WebViewStatics", content::RegisterWebViewStatics}, };
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index 636a1980c2..7d95034344 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -4,6 +4,7 @@
#include "content/browser/android/content_startup_flags.h"
+#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -66,6 +67,8 @@ void SetContentCommandLineFlags(int max_render_process_count,
parsed_command_line->AppendSwitch(switches::kEnableOverlayFullscreenVideo);
parsed_command_line->AppendSwitch(switches::kEnableOverlayScrollbars);
parsed_command_line->AppendSwitch(switches::kEnableOverscrollNotifications);
+ parsed_command_line->AppendSwitchASCII(switches::kTouchAckTimeoutDelayMs,
+ "200");
// Run the GPU service as a thread in the browser instead of as a
// standalone process.
@@ -87,6 +90,12 @@ void SetContentCommandLineFlags(int max_render_process_count,
parsed_command_line->AppendSwitchNative(
switches::kRegisterPepperPlugins, plugin_descriptor);
}
+
+ // Disable profiler timing by default.
+ if (!parsed_command_line->HasSwitch(switches::kProfilerTiming)) {
+ parsed_command_line->AppendSwitchASCII(
+ switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
+ }
}
} // namespace content
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 2a53563c4f..7fb557f4df 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -68,13 +68,16 @@ using blink::WebGestureEvent;
using blink::WebInputEvent;
// Describes the type and enabled state of a select popup item.
-// Keep in sync with the value defined in SelectPopupDialog.java
-enum PopupItemType {
- POPUP_ITEM_TYPE_GROUP = 0,
- POPUP_ITEM_TYPE_DISABLED,
- POPUP_ITEM_TYPE_ENABLED
+namespace {
+
+enum {
+#define DEFINE_POPUP_ITEM_TYPE(name, value) POPUP_ITEM_TYPE_##name = value,
+#include "content/browser/android/popup_item_type_list.h"
+#undef DEFINE_POPUP_ITEM_TYPE
};
+} //namespace
+
namespace content {
namespace {
@@ -206,6 +209,11 @@ ContentViewCoreImpl::~ContentViewCoreImpl() {
notification_registrar_.RemoveAll();
}
+base::android::ScopedJavaLocalRef<jobject>
+ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv* env, jobject obj) {
+ return web_contents_->GetJavaWebContents();
+}
+
void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv* env,
jobject obj) {
DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj));
@@ -389,7 +397,7 @@ void ContentViewCoreImpl::UpdateFrameInfo(
overdraw_bottom_height);
}
-void ContentViewCoreImpl::SetTitle(const string16& title) {
+void ContentViewCoreImpl::SetTitle(const base::string16& title) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
if (obj.is_null())
@@ -438,7 +446,7 @@ void ContentViewCoreImpl::ShowSelectPopupMenu(
ScopedJavaLocalRef<jintArray> enabled_array(env,
env->NewIntArray(items.size()));
- std::vector<string16> labels;
+ std::vector<base::string16> labels;
labels.reserve(items.size());
for (size_t i = 0; i < items.size(); ++i) {
labels.push_back(items[i].label);
@@ -1121,37 +1129,6 @@ void ContentViewCoreImpl::MoveCaret(JNIEnv* env, jobject obj,
}
}
-jboolean ContentViewCoreImpl::CanGoBack(JNIEnv* env, jobject obj) {
- return web_contents_->GetController().CanGoBack();
-}
-
-jboolean ContentViewCoreImpl::CanGoForward(JNIEnv* env, jobject obj) {
- return web_contents_->GetController().CanGoForward();
-}
-
-jboolean ContentViewCoreImpl::CanGoToOffset(JNIEnv* env, jobject obj,
- jint offset) {
- return web_contents_->GetController().CanGoToOffset(offset);
-}
-
-void ContentViewCoreImpl::GoBack(JNIEnv* env, jobject obj) {
- web_contents_->GetController().GoBack();
-}
-
-void ContentViewCoreImpl::GoForward(JNIEnv* env, jobject obj) {
- web_contents_->GetController().GoForward();
-}
-
-void ContentViewCoreImpl::GoToOffset(JNIEnv* env, jobject obj, jint offset) {
- web_contents_->GetController().GoToOffset(offset);
-}
-
-void ContentViewCoreImpl::GoToNavigationIndex(JNIEnv* env,
- jobject obj,
- jint index) {
- web_contents_->GetController().GoToIndex(index);
-}
-
void ContentViewCoreImpl::LoadIfNecessary(JNIEnv* env, jobject obj) {
web_contents_->GetController().LoadIfNecessary();
}
@@ -1487,7 +1464,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env,
if (!callback) {
// No callback requested.
- rvh->ExecuteJavascriptInWebFrame(string16(), // frame_xpath
+ rvh->ExecuteJavascriptInWebFrame(base::string16(), // frame_xpath
ConvertJavaStringToUTF16(env, script));
return;
}
@@ -1500,7 +1477,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env,
base::Bind(&JavaScriptResultCallback, j_callback);
rvh->ExecuteJavascriptInWebFrameCallbackResult(
- string16(), // frame_xpath
+ base::string16(), // frame_xpath
ConvertJavaStringToUTF16(env, script),
c_callback);
}
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 0c3a5ec3ea..040d6e0417 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -68,6 +68,9 @@ class ContentViewCoreImpl : public ContentViewCore,
// Methods called from Java via JNI
// --------------------------------------------------------------------------
+ base::android::ScopedJavaLocalRef<jobject> GetWebContentsAndroid(JNIEnv* env,
+ jobject obj);
+
void OnJavaContentViewCoreDestroyed(JNIEnv* env, jobject obj);
// Notifies the ContentViewCore that items were selected in the currently
@@ -141,13 +144,6 @@ class ContentViewCoreImpl : public ContentViewCore,
jfloat x2, jfloat y2);
void MoveCaret(JNIEnv* env, jobject obj, jfloat x, jfloat y);
- jboolean CanGoBack(JNIEnv* env, jobject obj);
- jboolean CanGoForward(JNIEnv* env, jobject obj);
- jboolean CanGoToOffset(JNIEnv* env, jobject obj, jint offset);
- void GoBack(JNIEnv* env, jobject obj);
- void GoForward(JNIEnv* env, jobject obj);
- void GoToOffset(JNIEnv* env, jobject obj, jint offset);
- void GoToNavigationIndex(JNIEnv* env, jobject obj, jint index);
void LoadIfNecessary(JNIEnv* env, jobject obj);
void RequestRestoreLoad(JNIEnv* env, jobject obj);
void StopLoading(JNIEnv* env, jobject obj);
@@ -258,7 +254,7 @@ class ContentViewCoreImpl : public ContentViewCore,
int selection_start, int selection_end,
int composition_start, int composition_end,
bool show_ime_if_needed, bool require_ack);
- void SetTitle(const string16& title);
+ void SetTitle(const base::string16& title);
void OnBackgroundColorChanged(SkColor color);
bool HasFocus();
diff --git a/content/browser/android/content_view_statics.cc b/content/browser/android/content_view_statics.cc
index 917da58280..e176564c4a 100644
--- a/content/browser/android/content_view_statics.cc
+++ b/content/browser/android/content_view_statics.cc
@@ -62,8 +62,8 @@ void ResumeWebkitSharedTimers(const std::vector<int>& suspended_processes) {
// Returns the first substring consisting of the address of a physical location.
static jstring FindAddress(JNIEnv* env, jclass clazz, jstring addr) {
- string16 content_16 = ConvertJavaStringToUTF16(env, addr);
- string16 result_16;
+ base::string16 content_16 = ConvertJavaStringToUTF16(env, addr);
+ base::string16 result_16;
if (content::address_parser::FindAddress(content_16, &result_16))
return ConvertUTF16ToJavaString(env, result_16).Release();
return NULL;
diff --git a/content/browser/android/date_time_chooser_android.cc b/content/browser/android/date_time_chooser_android.cc
index be87a932e1..f6b50c9da4 100644
--- a/content/browser/android/date_time_chooser_android.cc
+++ b/content/browser/android/date_time_chooser_android.cc
@@ -4,17 +4,41 @@
#include "content/browser/android/date_time_chooser_android.h"
+#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
+#include "base/i18n/char_iterator.h"
+#include "content/common/date_time_suggestion.h"
#include "content/common/view_messages.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/render_view_host.h"
#include "jni/DateTimeChooserAndroid_jni.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
+using base::android::ConvertUTF16ToJavaString;
+namespace {
+
+string16 SanitizeSuggestionString(const string16& string) {
+ string16 trimmed = string.substr(0, 255);
+ icu::UnicodeString sanitized;
+ base::i18n::UTF16CharIterator sanitized_iterator(&trimmed);
+ while (!sanitized_iterator.end()) {
+ UChar c = sanitized_iterator.get();
+ if (u_isprint(c))
+ sanitized.append(c);
+ sanitized_iterator.Advance();
+ }
+ return string16(sanitized.getBuffer(),
+ static_cast<size_t>(sanitized.length()));
+}
+
+} // namespace
+
namespace content {
// DateTimeChooserAndroid implementation
@@ -40,25 +64,7 @@ void DateTimeChooserAndroid::InitializeDateInputTypes(
void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env,
jobject,
- int dialog_type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week) {
- ViewHostMsg_DateTimeDialogValue_Params value;
- value.year = year;
- value.month = month;
- value.day = day;
- value.hour = hour;
- value.minute = minute;
- value.second = second;
- value.milli = milli;
- value.week = week;
- value.dialog_type = dialog_type;
+ jdouble value) {
host_->Send(new ViewMsg_ReplaceDateTime(host_->GetRoutingID(), value));
}
@@ -66,39 +72,46 @@ void DateTimeChooserAndroid::CancelDialog(JNIEnv* env, jobject) {
host_->Send(new ViewMsg_CancelDateTimeDialog(host_->GetRoutingID()));
}
-void DateTimeChooserAndroid::ShowDialog(ContentViewCore* content,
- RenderViewHost* host,
- int type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week,
- double min,
- double max,
- double step) {
+void DateTimeChooserAndroid::ShowDialog(
+ ContentViewCore* content,
+ RenderViewHost* host,
+ ui::TextInputType dialog_type,
+ double dialog_value,
+ double min,
+ double max,
+ double step,
+ const std::vector<DateTimeSuggestion>& suggestions) {
host_ = host;
JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobjectArray> suggestions_array;
+
+ if (suggestions.size() > 0) {
+ suggestions_array =
+ Java_DateTimeChooserAndroid_createSuggestionsArray(env,
+ suggestions.size());
+ for (size_t i = 0; i < suggestions.size(); ++i) {
+ const content::DateTimeSuggestion& suggestion = suggestions[i];
+ ScopedJavaLocalRef<jstring> localized_value = ConvertUTF16ToJavaString(
+ env, SanitizeSuggestionString(suggestion.localized_value));
+ ScopedJavaLocalRef<jstring> label = ConvertUTF16ToJavaString(
+ env, SanitizeSuggestionString(suggestion.label));
+ Java_DateTimeChooserAndroid_setDateTimeSuggestionAt(env,
+ suggestions_array.obj(), i,
+ suggestion.value, localized_value.obj(), label.obj());
+ }
+ }
+
j_date_time_chooser_.Reset(Java_DateTimeChooserAndroid_createDateTimeChooser(
env,
content->GetJavaObject().obj(),
reinterpret_cast<intptr_t>(this),
- type,
- year,
- month,
- day,
- hour,
- minute,
- second,
- milli,
- week,
+ dialog_type,
+ dialog_value,
min,
max,
- step));
+ step,
+ suggestions_array.obj()));
}
// ----------------------------------------------------------------------------
diff --git a/content/browser/android/date_time_chooser_android.h b/content/browser/android/date_time_chooser_android.h
index a5578e01b8..c02ecf56fe 100644
--- a/content/browser/android/date_time_chooser_android.h
+++ b/content/browser/android/date_time_chooser_android.h
@@ -6,14 +6,17 @@
#define CONTENT_BROWSER_ANDROID_DATE_TIME_CHOOSER_ANDROID_H_
#include <string>
+#include <vector>
#include "base/android/jni_helper.h"
#include "base/memory/scoped_ptr.h"
+#include "ui/base/ime/text_input_type.h"
namespace content {
class ContentViewCore;
class RenderViewHost;
+struct DateTimeSuggestion;
// Android implementation for DateTimeChooser dialogs.
class DateTimeChooserAndroid {
@@ -22,33 +25,19 @@ class DateTimeChooserAndroid {
~DateTimeChooserAndroid();
// DateTimeChooser implementation:
+ // Shows the dialog. |dialog_value| is the date/time value converted to a
+ // number as defined in HTML. (See blink::InputType::parseToNumber())
void ShowDialog(ContentViewCore* content,
RenderViewHost* host,
- int type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week,
+ ui::TextInputType dialog_type,
+ double dialog_value,
double min,
double max,
- double step);
-
- // Replaces the current value with the one passed the different fields
- void ReplaceDateTime(JNIEnv* env,
- jobject,
- jint dialog_type,
- jint year,
- jint month,
- jint day,
- jint hour,
- jint minute,
- jint second,
- jint milli,
- jint week);
+ double step,
+ const std::vector<DateTimeSuggestion>& suggestions);
+
+ // Replaces the current value
+ void ReplaceDateTime(JNIEnv* env, jobject, jdouble value);
// Closes the dialog without propagating any changes.
void CancelDialog(JNIEnv* env, jobject);
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.cc b/content/browser/android/in_process/synchronous_input_event_filter.cc
index 5b086fb716..b8ba0ea335 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.cc
+++ b/content/browser/android/in_process/synchronous_input_event_filter.cc
@@ -28,8 +28,8 @@ InputEventAckState SynchronousInputEventFilter::HandleInputEvent(
// state. While not good, it should also not be fatal.
if (handler_.is_null())
return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
-
- return handler_.Run(routing_id, &input_event, ui::LatencyInfo());
+ ui::LatencyInfo latency;
+ return handler_.Run(routing_id, &input_event, &latency);
}
void SynchronousInputEventFilter::SetBoundHandler(const Handler& handler) {
diff --git a/content/browser/android/overscroll_glow.cc b/content/browser/android/overscroll_glow.cc
index d8e8c77575..8e08de45ec 100644
--- a/content/browser/android/overscroll_glow.cc
+++ b/content/browser/android/overscroll_glow.cc
@@ -6,6 +6,7 @@
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
+#include "base/threading/worker_pool.h"
#include "cc/layers/image_layer.h"
#include "content/browser/android/edge_effect.h"
#include "ui/gfx/android/java_bitmap.h"
@@ -63,54 +64,61 @@ gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) {
return vector;
}
-} // namespace
+// Force loading of any necessary resources. This function is thread-safe.
+void EnsureResources() {
+ g_overscroll_resources.Get();
+}
-scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled,
- gfx::SizeF size) {
- const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap();
- const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap();
- if (edge.isNull() || glow.isNull())
- return scoped_ptr<OverscrollGlow>();
+} // namespace
- return make_scoped_ptr(new OverscrollGlow(enabled, size, edge, glow));
-}
+scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled) {
+ // Don't block the main thread with effect resource loading during creation.
+ // Effect instantiation is deferred until the effect overscrolls, in which
+ // case the main thread may block until the resource has loaded.
+ if (enabled && g_overscroll_resources == NULL)
+ base::WorkerPool::PostTask(FROM_HERE, base::Bind(EnsureResources), true);
-void OverscrollGlow::EnsureResources() {
- g_overscroll_resources.Get();
+ return make_scoped_ptr(new OverscrollGlow(enabled));
}
-OverscrollGlow::OverscrollGlow(bool enabled,
- gfx::SizeF size,
- const SkBitmap& edge,
- const SkBitmap& glow)
+OverscrollGlow::OverscrollGlow(bool enabled)
: enabled_(enabled),
- size_(size),
+ initialized_(false),
horizontal_overscroll_enabled_(true),
- vertical_overscroll_enabled_(true),
- root_layer_(cc::Layer::Create()) {
- for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
- scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge);
- scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow);
- root_layer_->AddChild(edge_layer);
- root_layer_->AddChild(glow_layer);
- edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer));
- }
-}
+ vertical_overscroll_enabled_(true) {}
OverscrollGlow::~OverscrollGlow() {
- root_layer_->RemoveFromParent();
+ Detach();
+}
+
+void OverscrollGlow::Enable() {
+ enabled_ = true;
}
-void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time,
+void OverscrollGlow::Disable() {
+ if (!enabled_)
+ return;
+ enabled_ = false;
+ if (!enabled_ && initialized_) {
+ Detach();
+ for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i)
+ edge_effects_[i]->Finish();
+ }
+}
+
+bool OverscrollGlow::OnOverscrolled(cc::Layer* overscrolling_layer,
+ base::TimeTicks current_time,
gfx::Vector2dF overscroll,
gfx::Vector2dF velocity) {
+ DCHECK(overscrolling_layer);
+
if (!enabled_)
- return;
+ return false;
// The size of the glow determines the relative effect of the inputs; an
// empty-sized effect is effectively disabled.
if (size_.IsEmpty())
- return;
+ return false;
if (!horizontal_overscroll_enabled_) {
overscroll.set_x(0);
@@ -126,10 +134,16 @@ void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time,
velocity = ZeroSmallComponents(velocity);
if (overscroll.IsZero()) {
- Release(current_time);
- return;
+ if (initialized_) {
+ Release(current_time);
+ UpdateLayerAttachment(overscrolling_layer);
+ }
+ return NeedsAnimate();
}
+ if (!InitializeIfNecessary())
+ return false;
+
if (!velocity.IsZero()) {
// Release effects if scrolling has changed directions.
if (velocity.x() * old_velocity_.x() < 0)
@@ -152,11 +166,16 @@ void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time,
old_velocity_ = velocity;
old_overscroll_ = overscroll;
+
+ UpdateLayerAttachment(overscrolling_layer);
+ return NeedsAnimate();
}
bool OverscrollGlow::Animate(base::TimeTicks current_time) {
- if (!NeedsAnimate())
+ if (!NeedsAnimate()) {
+ Detach();
return false;
+ }
const gfx::SizeF sizes[EdgeEffect::EDGE_COUNT] = {
size_, gfx::SizeF(size_.height(), size_.width()),
@@ -170,21 +189,16 @@ bool OverscrollGlow::Animate(base::TimeTicks current_time) {
}
}
- return NeedsAnimate();
-}
-
-void OverscrollGlow::SetEnabled(bool enabled) {
- if (enabled_ == enabled)
- return;
- enabled_ = enabled;
- if (!enabled_) {
- for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i)
- edge_effects_[i]->Finish();
+ if (!NeedsAnimate()) {
+ Detach();
+ return false;
}
+
+ return true;
}
bool OverscrollGlow::NeedsAnimate() const {
- if (!enabled_)
+ if (!enabled_ || !initialized_)
return false;
for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
if (!edge_effects_[i]->IsFinished())
@@ -193,8 +207,54 @@ bool OverscrollGlow::NeedsAnimate() const {
return false;
}
+void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent) {
+ DCHECK(parent);
+ if (!root_layer_)
+ return;
+
+ if (!NeedsAnimate()) {
+ Detach();
+ return;
+ }
+
+ if (root_layer_->parent() != parent)
+ parent->AddChild(root_layer_);
+}
+
+void OverscrollGlow::Detach() {
+ if (root_layer_)
+ root_layer_->RemoveFromParent();
+}
+
+bool OverscrollGlow::InitializeIfNecessary() {
+ DCHECK(enabled_);
+ if (initialized_)
+ return true;
+
+ const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap();
+ const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap();
+ if (edge.isNull() || glow.isNull()) {
+ Disable();
+ return false;
+ }
+
+ DCHECK(!root_layer_);
+ root_layer_ = cc::Layer::Create();
+ for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
+ scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge);
+ scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow);
+ root_layer_->AddChild(edge_layer);
+ root_layer_->AddChild(glow_layer);
+ edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer));
+ }
+
+ initialized_ = true;
+ return true;
+}
+
void OverscrollGlow::Pull(base::TimeTicks current_time,
gfx::Vector2dF overscroll_delta) {
+ DCHECK(enabled_ && initialized_);
overscroll_delta = ZeroSmallComponents(overscroll_delta);
if (overscroll_delta.IsZero())
return;
@@ -222,6 +282,7 @@ void OverscrollGlow::Absorb(base::TimeTicks current_time,
gfx::Vector2dF velocity,
gfx::Vector2dF overscroll,
gfx::Vector2dF old_overscroll) {
+ DCHECK(enabled_ && initialized_);
if (overscroll.IsZero() || velocity.IsZero())
return;
@@ -243,6 +304,7 @@ void OverscrollGlow::Absorb(base::TimeTicks current_time,
}
void OverscrollGlow::Release(base::TimeTicks current_time) {
+ DCHECK(initialized_);
for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
edge_effects_[i]->Release(current_time);
}
@@ -250,6 +312,7 @@ void OverscrollGlow::Release(base::TimeTicks current_time) {
}
void OverscrollGlow::ReleaseAxis(Axis axis, base::TimeTicks current_time) {
+ DCHECK(initialized_);
switch (axis) {
case AXIS_X:
edge_effects_[EdgeEffect::EDGE_LEFT]->Release(current_time);
@@ -267,6 +330,7 @@ void OverscrollGlow::ReleaseAxis(Axis axis, base::TimeTicks current_time) {
}
EdgeEffect* OverscrollGlow::GetOppositeEdge(int edge_index) {
+ DCHECK(initialized_);
return edge_effects_[(edge_index + 2) % EdgeEffect::EDGE_COUNT].get();
}
diff --git a/content/browser/android/overscroll_glow.h b/content/browser/android/overscroll_glow.h
index ba1d48ff74..3a13fb3c4f 100644
--- a/content/browser/android/overscroll_glow.h
+++ b/content/browser/android/overscroll_glow.h
@@ -26,38 +26,35 @@ namespace content {
*/
class OverscrollGlow {
public:
- // Create and initialize a new effect with the necessary resources.
- // If |enabled| is false, the effect will be be deactivated until
- // SetEnabled(true) is called.
- // The caller should attach |root_layer| to the desired layer tree.
- static scoped_ptr<OverscrollGlow> Create(bool enabled, gfx::SizeF size);
-
- // Force loading of any necessary resources. This function is thread-safe.
- static void EnsureResources();
+ // Create a new effect. If |enabled| is false, the effect will remain
+ // deactivated until explicitly enabled.
+ // Note: No resources will be allocated until the effect is both
+ // enabled and an overscroll event has occurred.
+ static scoped_ptr<OverscrollGlow> Create(bool enabled);
~OverscrollGlow();
- // If false, the glow will be deactivated, and subsequent calls to
- // OnOverscrolled or Animate will have no effect.
- void SetEnabled(bool enabled);
+ // Enable the effect. If the effect was previously disabled, it will remain
+ // dormant until subsequent calls to |OnOverscrolled()|.
+ void Enable();
+
+ // Deactivate and detach the effect. Subsequent calls to |OnOverscrolled()| or
+ // |Animate()| will have no effect.
+ void Disable();
+ // Effect layers will be attached to |overscrolling_layer| if necessary.
// |overscroll| is the accumulated overscroll for the current gesture.
// |velocity| is the instantaneous velocity for the overscroll.
- void OnOverscrolled(base::TimeTicks current_time,
+ // Returns true if the effect still needs animation ticks.
+ bool OnOverscrolled(cc::Layer* overscrolling_layer,
+ base::TimeTicks current_time,
gfx::Vector2dF overscroll,
gfx::Vector2dF velocity);
// Returns true if the effect still needs animation ticks.
+ // Note: The effect will detach itself when no further animation is required.
bool Animate(base::TimeTicks current_time);
- // Returns true if the effect needs animation ticks.
- bool NeedsAnimate() const;
-
- // The root layer of the effect (not necessarily of the tree).
- scoped_refptr<cc::Layer> root_layer() const {
- return root_layer_;
- }
-
// Horizontal overscroll will be ignored when false.
void set_horizontal_overscroll_enabled(bool enabled) {
horizontal_overscroll_enabled_ = enabled;
@@ -74,11 +71,13 @@ class OverscrollGlow {
private:
enum Axis { AXIS_X, AXIS_Y };
- OverscrollGlow(bool enabled,
- gfx::SizeF size,
- const SkBitmap& edge,
- const SkBitmap& glow);
+ OverscrollGlow(bool enabled);
+ // Returns whether the effect is initialized.
+ bool InitializeIfNecessary();
+ bool NeedsAnimate() const;
+ void UpdateLayerAttachment(cc::Layer* parent);
+ void Detach();
void Pull(base::TimeTicks current_time,
gfx::Vector2dF added_overscroll);
void Absorb(base::TimeTicks current_time,
@@ -93,6 +92,7 @@ class OverscrollGlow {
scoped_ptr<EdgeEffect> edge_effects_[EdgeEffect::EDGE_COUNT];
bool enabled_;
+ bool initialized_;
gfx::SizeF size_;
gfx::Vector2dF old_overscroll_;
gfx::Vector2dF old_velocity_;
diff --git a/content/browser/android/popup_item_type_list.h b/content/browser/android/popup_item_type_list.h
new file mode 100644
index 0000000000..3f50490f61
--- /dev/null
+++ b/content/browser/android/popup_item_type_list.h
@@ -0,0 +1,23 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file intentionally does not have header guards because this file
+// is meant to be included inside a macro to generate enum values.
+
+// This file contains a list of sync PopupItemTypes which describe the type
+// and enabled state of a select popup item. List is used by Android when
+// displaying a new select popup menu.
+
+#ifndef DEFINE_POPUP_ITEM_TYPE
+#error "Please define DEFINE_POPUP_ITEM_TYPE before including this file."
+#endif
+
+// Popup item is of type group
+DEFINE_POPUP_ITEM_TYPE(GROUP, 0)
+
+// Popup item is disabled
+DEFINE_POPUP_ITEM_TYPE(DISABLED, 1)
+
+// Popup item is enabled
+DEFINE_POPUP_ITEM_TYPE(ENABLED, 2)
diff --git a/content/browser/android/tracing_controller_android.cc b/content/browser/android/tracing_controller_android.cc
index 42d147e821..75ac6d7c23 100644
--- a/content/browser/android/tracing_controller_android.cc
+++ b/content/browser/android/tracing_controller_android.cc
@@ -6,12 +6,9 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
-#include "base/command_line.h"
#include "base/debug/trace_event.h"
-#include "base/files/file_path.h"
#include "base/logging.h"
-#include "content/browser/tracing/trace_subscriber_stdio.h"
-#include "content/public/browser/trace_controller.h"
+#include "content/public/browser/tracing_controller.h"
#include "jni/TracingControllerAndroid_jni.h"
namespace content {
@@ -21,29 +18,9 @@ static jlong Init(JNIEnv* env, jobject obj) {
return reinterpret_cast<intptr_t>(profiler);
}
-class TracingControllerAndroid::Subscriber
- : public content::TraceSubscriberStdio {
- public:
- Subscriber(TracingControllerAndroid* profiler, const base::FilePath& path)
- : TraceSubscriberStdio(path, FILE_TYPE_ARRAY, false),
- profiler_(profiler) {}
-
- void set_profiler(TracingControllerAndroid* profiler) {
- CHECK(!profiler_);
- profiler_ = profiler;
- }
-
- virtual void OnEndTracingComplete() OVERRIDE {
- TraceSubscriberStdio::OnEndTracingComplete();
- profiler_->OnTracingStopped();
- }
-
- private:
- TracingControllerAndroid* profiler_;
-};
-
TracingControllerAndroid::TracingControllerAndroid(JNIEnv* env, jobject obj)
- : weak_java_object_(env, obj) {}
+ : weak_java_object_(env, obj),
+ weak_factory_(this) {}
TracingControllerAndroid::~TracingControllerAndroid() {}
@@ -56,39 +33,37 @@ bool TracingControllerAndroid::StartTracing(JNIEnv* env,
jstring jfilename,
jstring jcategories,
jboolean record_continuously) {
- if (subscriber_.get()) {
- return false;
- }
- std::string filename = base::android::ConvertJavaStringToUTF8(env, jfilename);
+ file_path_ = base::FilePath(
+ base::android::ConvertJavaStringToUTF8(env, jfilename));
std::string categories =
base::android::ConvertJavaStringToUTF8(env, jcategories);
- subscriber_.reset(new Subscriber(this, base::FilePath(filename)));
- return TraceController::GetInstance()->BeginTracing(
- subscriber_.get(),
+
+ // This log is required by adb_profile_chrome.py.
+ LOG(WARNING) << "Logging performance trace to file: " << file_path_.value();
+
+ return TracingController::GetInstance()->EnableRecording(
categories,
- record_continuously ? base::debug::TraceLog::RECORD_CONTINUOUSLY
- : base::debug::TraceLog::RECORD_UNTIL_FULL);
+ record_continuously ? TracingController::RECORD_CONTINUOUSLY
+ : TracingController::DEFAULT_OPTIONS,
+ TracingController::EnableRecordingDoneCallback());
}
void TracingControllerAndroid::StopTracing(JNIEnv* env, jobject obj) {
- if (!subscriber_.get()) {
- return;
- }
- TraceController* controller = TraceController::GetInstance();
- if (!controller->EndTracingAsync(subscriber_.get())) {
+ if (!TracingController::GetInstance()->DisableRecording(
+ file_path_,
+ base::Bind(&TracingControllerAndroid::OnTracingStopped,
+ weak_factory_.GetWeakPtr()))) {
LOG(ERROR) << "EndTracingAsync failed, forcing an immediate stop";
- controller->CancelSubscriber(subscriber_.get());
- OnTracingStopped();
+ OnTracingStopped(file_path_);
}
}
-void TracingControllerAndroid::OnTracingStopped() {
+void TracingControllerAndroid::OnTracingStopped(
+ const base::FilePath& file_path) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> obj = weak_java_object_.get(env);
- if (obj.obj()) {
+ if (obj.obj())
Java_TracingControllerAndroid_onTracingStopped(env, obj.obj());
- }
- subscriber_.reset();
}
static jstring GetDefaultCategories(JNIEnv* env, jobject obj) {
diff --git a/content/browser/android/tracing_controller_android.h b/content/browser/android/tracing_controller_android.h
index 0cd310ebb6..4d70e7b75e 100644
--- a/content/browser/android/tracing_controller_android.h
+++ b/content/browser/android/tracing_controller_android.h
@@ -6,7 +6,8 @@
#define CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_
#include "base/android/jni_helper.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
namespace content {
@@ -25,12 +26,11 @@ class TracingControllerAndroid {
private:
~TracingControllerAndroid();
- void OnTracingStopped();
+ void OnTracingStopped(const base::FilePath& file_path);
JavaObjectWeakGlobalRef weak_java_object_;
-
- class Subscriber;
- scoped_ptr<Subscriber> subscriber_;
+ base::FilePath file_path_;
+ base::WeakPtrFactory<TracingControllerAndroid> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TracingControllerAndroid);
};
diff --git a/content/browser/android/web_contents_observer_android.cc b/content/browser/android/web_contents_observer_android.cc
index f2494e8f63..235041be67 100644
--- a/content/browser/android/web_contents_observer_android.cc
+++ b/content/browser/android/web_contents_observer_android.cc
@@ -98,11 +98,11 @@ void WebContentsObserverAndroid::DidStopLoading(
void WebContentsObserverAndroid::DidFailProvisionalLoad(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) {
DidFailLoadInternal(
true, is_main_frame, error_code, error_description, validated_url);
@@ -113,7 +113,7 @@ void WebContentsObserverAndroid::DidFailLoad(
const GURL& validated_url,
bool is_main_frame,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) {
DidFailLoadInternal(
false, is_main_frame, error_code, error_description, validated_url);
@@ -175,7 +175,7 @@ void WebContentsObserverAndroid::DidStartProvisionalLoadForFrame(
void WebContentsObserverAndroid::DidCommitProvisionalLoadForFrame(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -251,7 +251,7 @@ void WebContentsObserverAndroid::DidFailLoadInternal(
bool is_provisional_load,
bool is_main_frame,
int error_code,
- const string16& description,
+ const base::string16& description,
const GURL& url) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
diff --git a/content/browser/android/web_contents_observer_android.h b/content/browser/android/web_contents_observer_android.h
index 9742d2827e..15a136390f 100644
--- a/content/browser/android/web_contents_observer_android.h
+++ b/content/browser/android/web_contents_observer_android.h
@@ -38,17 +38,17 @@ class WebContentsObserverAndroid : public WebContentsObserver {
virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE;
virtual void DidFailProvisionalLoad(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE;
virtual void DidFailLoad(int64 frame_id,
const GURL& validated_url,
bool is_main_frame,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE;
virtual void DidNavigateMainFrame(const LoadCommittedDetails& details,
const FrameNavigateParams& params) OVERRIDE;
@@ -64,7 +64,7 @@ class WebContentsObserverAndroid : public WebContentsObserver {
RenderViewHost* render_view_host) OVERRIDE;
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -83,7 +83,7 @@ class WebContentsObserverAndroid : public WebContentsObserver {
void DidFailLoadInternal(bool is_provisional_load,
bool is_main_frame,
int error_code,
- const string16& description,
+ const base::string16& description,
const GURL& url);
JavaObjectWeakGlobalRef weak_java_observer_;
diff --git a/content/browser/aura/gpu_process_transport_factory.cc b/content/browser/aura/gpu_process_transport_factory.cc
index 20b4ea5fa0..21091346e6 100644
--- a/content/browser/aura/gpu_process_transport_factory.cc
+++ b/content/browser/aura/gpu_process_transport_factory.cc
@@ -179,7 +179,7 @@ scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice(
}
scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
- ui::Compositor* compositor) {
+ ui::Compositor* compositor, bool software_fallback) {
PerCompositorData* data = per_compositor_data_[compositor];
if (!data)
data = CreatePerCompositorData(compositor);
@@ -187,7 +187,8 @@ scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
scoped_refptr<ContextProviderCommandBuffer> context_provider;
CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (!command_line->HasSwitch(switches::kUIEnableSoftwareCompositing)) {
+ if (!command_line->HasSwitch(switches::kUIEnableSoftwareCompositing) &&
+ !software_fallback) {
context_provider = ContextProviderCommandBuffer::Create(
GpuProcessTransportFactory::CreateContextCommon(data->surface_id),
"Compositor");
@@ -293,7 +294,8 @@ gfx::GLSurfaceHandle GpuProcessTransportFactory::CreateSharedSurfaceHandle() {
gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle(
gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT);
handle.parent_gpu_process_id = context->GetGPUProcessID();
- handle.parent_client_id = context->GetChannelID();
+ handle.parent_client_id =
+ BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
return handle;
}
@@ -451,13 +453,11 @@ GpuProcessTransportFactory::CreateContextCommon(int surface_id) {
if (!gpu_channel_host)
return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
- bool use_echo_for_swap_ack = true;
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
new WebGraphicsContext3DCommandBufferImpl(
surface_id,
url,
gpu_channel_host.get(),
- use_echo_for_swap_ack,
attrs,
false,
WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits()));
diff --git a/content/browser/aura/gpu_process_transport_factory.h b/content/browser/aura/gpu_process_transport_factory.h
index 36ebb00700..13da92b253 100644
--- a/content/browser/aura/gpu_process_transport_factory.h
+++ b/content/browser/aura/gpu_process_transport_factory.h
@@ -36,7 +36,7 @@ class GpuProcessTransportFactory
// ui::ContextFactory implementation.
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
- ui::Compositor* compositor) OVERRIDE;
+ ui::Compositor* compositor, bool software_fallback) OVERRIDE;
virtual scoped_refptr<ui::Reflector> CreateReflector(
ui::Compositor* source,
ui::Layer* target) OVERRIDE;
diff --git a/content/browser/aura/owned_mailbox.cc b/content/browser/aura/owned_mailbox.cc
new file mode 100644
index 0000000000..1a99d335ac
--- /dev/null
+++ b/content/browser/aura/owned_mailbox.cc
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aura/owned_mailbox.h"
+
+#include "base/logging.h"
+#include "content/browser/aura/image_transport_factory.h"
+#include "content/common/gpu/client/gl_helper.h"
+
+namespace content {
+
+OwnedMailbox::OwnedMailbox(GLHelper* gl_helper)
+ : texture_id_(0), sync_point_(0), gl_helper_(gl_helper) {
+ texture_id_ = gl_helper_->CreateTexture();
+ mailbox_ = gl_helper_->ProduceMailboxFromTexture(texture_id_, &sync_point_);
+ ImageTransportFactory::GetInstance()->AddObserver(this);
+}
+
+OwnedMailbox::~OwnedMailbox() {
+ ImageTransportFactory::GetInstance()->RemoveObserver(this);
+ if (gl_helper_) {
+ gl_helper_->WaitSyncPoint(sync_point_);
+ gl_helper_->DeleteTexture(texture_id_);
+ }
+}
+
+void OwnedMailbox::UpdateSyncPoint(uint32 sync_point) {
+ if (sync_point)
+ sync_point_ = sync_point;
+}
+
+void OwnedMailbox::OnLostResources() {
+ gl_helper_->WaitSyncPoint(sync_point_);
+ gl_helper_->DeleteTexture(texture_id_);
+ texture_id_ = 0;
+ mailbox_ = gpu::Mailbox();
+ sync_point_ = 0;
+ gl_helper_ = NULL;
+}
+
+} // namespace content
diff --git a/content/browser/aura/owned_mailbox.h b/content/browser/aura/owned_mailbox.h
new file mode 100644
index 0000000000..ea1c242bf7
--- /dev/null
+++ b/content/browser/aura/owned_mailbox.h
@@ -0,0 +1,41 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ref_counted.h"
+#include "content/browser/aura/image_transport_factory.h"
+#include "gpu/command_buffer/common/mailbox.h"
+
+namespace content {
+
+class GLHelper;
+
+// This class holds a texture id and gpu::Mailbox, and deletes the texture
+// id when the object itself is destroyed. Should only be created if a GLHelper
+// exists on the ImageTransportFactory.
+class OwnedMailbox : public base::RefCounted<OwnedMailbox>,
+ public ImageTransportFactoryObserver {
+ public:
+ explicit OwnedMailbox(GLHelper* gl_helper);
+
+ uint32 texture_id() const { return texture_id_; }
+ uint32 sync_point() const { return sync_point_; }
+ const gpu::Mailbox& mailbox() const { return mailbox_; }
+
+ void UpdateSyncPoint(uint32 sync_point);
+
+ protected:
+ virtual ~OwnedMailbox();
+
+ virtual void OnLostResources() OVERRIDE;
+
+ private:
+ friend class base::RefCounted<OwnedMailbox>;
+
+ uint32 texture_id_;
+ gpu::Mailbox mailbox_;
+ uint32 sync_point_;
+ GLHelper* gl_helper_;
+};
+
+} // namespace content
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index 8e6bde3b0a..4261572334 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -192,7 +192,7 @@ base::ProcessHandle BrowserChildProcessHostImpl::GetHandle() const {
return child_process_->GetHandle();
}
-void BrowserChildProcessHostImpl::SetName(const string16& name) {
+void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
data_.name = name;
}
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h
index 6345595a14..428da3ddaf 100644
--- a/content/browser/browser_child_process_host_impl.h
+++ b/content/browser/browser_child_process_host_impl.h
@@ -54,7 +54,7 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
virtual ChildProcessHost* GetHost() const OVERRIDE;
virtual base::TerminationStatus GetTerminationStatus(
bool known_dead, int* exit_code) OVERRIDE;
- virtual void SetName(const string16& name) OVERRIDE;
+ virtual void SetName(const base::string16& name) OVERRIDE;
virtual void SetHandle(base::ProcessHandle handle) OVERRIDE;
// Returns the handle of the child process. This can be called only after
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 093aef3d0f..9b4a1ef6a5 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -34,6 +34,7 @@
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/histogram_synchronizer.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/media/media_internals.h"
#include "content/browser/net/browser_online_state_observer.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/media/audio_mirroring_manager.h"
@@ -462,7 +463,8 @@ void BrowserMainLoop::MainMessageLoopStart() {
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan")
- audio_manager_.reset(media::AudioManager::Create());
+ audio_manager_.reset(media::AudioManager::Create(
+ MediaInternals::GetInstance()));
}
{
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MIDIManager")
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 7d166a60ae..ef8d7791c5 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -351,6 +351,7 @@ BrowserPluginGuest::BrowserPluginGuest(
mouse_locked_(false),
pending_lock_request_(false),
embedder_visible_(true),
+ copy_request_id_(0),
next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID),
has_render_view_(has_render_view),
last_seen_auto_size_enabled_(false),
@@ -365,9 +366,9 @@ BrowserPluginGuest::BrowserPluginGuest(
bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
if (!delegate_)
return false;
@@ -507,6 +508,8 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
OnSwapBuffersACK)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameACK,
OnCompositorFrameACK)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck,
+ OnCopyFromCompositingSurfaceAck)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate,
OnDragStatusUpdate)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand,
@@ -625,6 +628,9 @@ void BrowserPluginGuest::Initialize(
ack_params.name = name_;
SendMessageToEmbedder(
new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params));
+
+ if (delegate_)
+ delegate_->DidAttach();
}
BrowserPluginGuest::~BrowserPluginGuest() {
@@ -683,6 +689,16 @@ void BrowserPluginGuest::UpdateVisibility() {
OnSetVisibility(instance_id_, visible());
}
+void BrowserPluginGuest::CopyFromCompositingSurface(
+ gfx::Rect src_subrect,
+ gfx::Size dst_size,
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
+ copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback));
+ SendMessageToEmbedder(
+ new BrowserPluginMsg_CopyFromCompositingSurface(instance_id(),
+ copy_request_id_, src_subrect, dst_size));
+}
+
// screen.
gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
gfx::Rect guest_rect(bounds);
@@ -758,6 +774,9 @@ void BrowserPluginGuest::HandleKeyboardEvent(
if (delegate_ && delegate_->HandleKeyboardEvent(event))
return;
+ if (!embedder_web_contents_->GetDelegate())
+ return;
+
// Send the unhandled keyboard events back to the embedder to reprocess them.
// TODO(fsamuel): This introduces the possibility of out-of-order keyboard
// events because the guest may be arbitrarily delayed when responding to
@@ -796,7 +815,7 @@ WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
- const string16& frame_name,
+ const base::string16& frame_name,
const GURL& target_url,
WebContents* new_contents) {
WebContentsImpl* new_contents_impl =
@@ -828,6 +847,12 @@ void BrowserPluginGuest::RendererResponsive(WebContents* source) {
void BrowserPluginGuest::RunFileChooser(WebContents* web_contents,
const FileChooserParams& params) {
+ if (!attached())
+ return;
+
+ if (!embedder_web_contents_->GetDelegate())
+ return;
+
embedder_web_contents_->GetDelegate()->RunFileChooser(web_contents, params);
}
@@ -1028,7 +1053,7 @@ void BrowserPluginGuest::SendQueuedMessages() {
void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -1045,7 +1070,7 @@ void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
const char script[] = "window.addEventListener('dragstart', function() { "
" window.event.preventDefault(); "
"});";
- render_view_host->ExecuteJavascriptInWebFrame(string16(),
+ render_view_host->ExecuteJavascriptInWebFrame(base::string16(),
ASCIIToUTF16(script));
}
}
@@ -1109,6 +1134,7 @@ bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
switch (message.type()) {
case BrowserPluginHostMsg_BuffersSwappedACK::ID:
case BrowserPluginHostMsg_CompositorFrameACK::ID:
+ case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID:
case BrowserPluginHostMsg_DragStatusUpdate::ID:
case BrowserPluginHostMsg_ExecuteEditCommand::ID:
case BrowserPluginHostMsg_HandleInputEvent::ID:
@@ -1377,7 +1403,8 @@ void BrowserPluginGuest::OnNavigateGuest(
if (scheme_is_blocked || !url.is_valid()) {
if (delegate_) {
std::string error_type;
- RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", &error_type);
+ base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::",
+ &error_type);
delegate_->LoadAbort(true /* is_top_level */, url, error_type);
}
return;
@@ -1428,15 +1455,10 @@ void BrowserPluginGuest::OnResizeGuest(
}
// Invalid damage buffer means we are in HW compositing mode,
// so just resize the WebContents and repaint if needed.
- if (!base::SharedMemory::IsHandleValid(params.damage_buffer_handle)) {
- if (!params.view_rect.size().IsEmpty())
- GetWebContents()->GetView()->SizeContents(params.view_rect.size());
- if (params.repaint)
- Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size()));
- return;
- }
- SetDamageBuffer(params);
- GetWebContents()->GetView()->SizeContents(params.view_rect.size());
+ if (base::SharedMemory::IsHandleValid(params.damage_buffer_handle))
+ SetDamageBuffer(params);
+ if (!params.view_rect.size().IsEmpty())
+ GetWebContents()->GetView()->SizeContents(params.view_rect.size());
if (params.repaint)
Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size()));
}
@@ -1556,6 +1578,18 @@ void BrowserPluginGuest::OnUpdateRectACK(
OnSetSize(instance_id_, auto_size_params, resize_guest_params);
}
+void BrowserPluginGuest::OnCopyFromCompositingSurfaceAck(
+ int instance_id,
+ int request_id,
+ const SkBitmap& bitmap) {
+ CHECK(copy_request_callbacks_.count(request_id));
+ if (!copy_request_callbacks_.count(request_id))
+ return;
+ const CopyRequestCallback& callback = copy_request_callbacks_[request_id];
+ callback.Run(!bitmap.empty() && !bitmap.isNull(), bitmap);
+ copy_request_callbacks_.erase(request_id);
+}
+
void BrowserPluginGuest::OnUpdateGeometry(int instance_id,
const gfx::Rect& view_rect) {
// The plugin has moved within the embedder without resizing or the
@@ -1633,8 +1667,8 @@ void BrowserPluginGuest::RunJavaScriptDialog(
const GURL& origin_url,
const std::string& accept_lang,
JavaScriptMessageType javascript_message_type,
- const string16& message_text,
- const string16& default_prompt_text,
+ const base::string16& message_text,
+ const base::string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) {
base::DictionaryValue request_info;
@@ -1659,18 +1693,18 @@ void BrowserPluginGuest::RunJavaScriptDialog(
void BrowserPluginGuest::RunBeforeUnloadDialog(
WebContents* web_contents,
- const string16& message_text,
+ const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) {
// This is called if the guest has a beforeunload event handler.
// This callback allows navigation to proceed.
- callback.Run(true, string16());
+ callback.Run(true, base::string16());
}
bool BrowserPluginGuest::HandleJavaScriptDialog(
WebContents* web_contents,
bool accept,
- const string16* prompt_override) {
+ const base::string16* prompt_override) {
return false;
}
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index 2a9c36cfb4..b3d491801f 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -144,10 +144,15 @@ class CONTENT_EXPORT BrowserPluginGuest
void UpdateVisibility();
+ void CopyFromCompositingSurface(
+ gfx::Rect src_subrect,
+ gfx::Size dst_size,
+ const base::Callback<void(bool, const SkBitmap&)>& callback);
+
// WebContentsObserver implementation.
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -161,9 +166,9 @@ class CONTENT_EXPORT BrowserPluginGuest
// WebContentsDelegate implementation.
virtual bool AddMessageToConsole(WebContents* source,
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) OVERRIDE;
+ const base::string16& source_id) OVERRIDE;
// If a new window is created with target="_blank" and rel="noreferrer", then
// this method is called, indicating that the new WebContents is ready to be
// attached.
@@ -189,7 +194,7 @@ class CONTENT_EXPORT BrowserPluginGuest
const OpenURLParams& params) OVERRIDE;
virtual void WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
- const string16& frame_name,
+ const base::string16& frame_name,
const GURL& target_url,
WebContents* new_contents) OVERRIDE;
virtual void RendererUnresponsive(WebContents* source) OVERRIDE;
@@ -208,18 +213,19 @@ class CONTENT_EXPORT BrowserPluginGuest
const GURL& origin_url,
const std::string& accept_lang,
JavaScriptMessageType javascript_message_type,
- const string16& message_text,
- const string16& default_prompt_text,
+ const base::string16& message_text,
+ const base::string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) OVERRIDE;
virtual void RunBeforeUnloadDialog(
WebContents* web_contents,
- const string16& message_text,
+ const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) OVERRIDE;
- virtual bool HandleJavaScriptDialog(WebContents* web_contents,
- bool accept,
- const string16* prompt_override) OVERRIDE;
+ virtual bool HandleJavaScriptDialog(
+ WebContents* web_contents,
+ bool accept,
+ const base::string16* prompt_override) OVERRIDE;
virtual void CancelActiveAndPendingDialogs(
WebContents* web_contents) OVERRIDE;
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
@@ -374,7 +380,9 @@ class CONTENT_EXPORT BrowserPluginGuest
uint32 output_surface_id,
int renderer_host_id,
const cc::CompositorFrameAck& ack);
-
+ void OnCopyFromCompositingSurfaceAck(int instance_id,
+ int request_id,
+ const SkBitmap& bitmap);
// Handles drag events from the embedder.
// When dragging, the drag events go to the embedder first, and if the drag
// happens on the browser plugin, then the plugin sends a corresponding
@@ -527,6 +535,13 @@ class CONTENT_EXPORT BrowserPluginGuest
gfx::Size max_auto_size_;
gfx::Size min_auto_size_;
+ // Each copy-request is identified by a unique number. The unique number is
+ // used to keep track of the right callback.
+ int copy_request_id_;
+ typedef base::Callback<void(bool, const SkBitmap&)> CopyRequestCallback;
+ typedef std::map<int, const CopyRequestCallback> CopyRequestMap;
+ CopyRequestMap copy_request_callbacks_;
+
typedef std::map<BrowserPluginGuest*, NewWindowInfo> PendingWindowMap;
PendingWindowMap pending_new_windows_;
base::WeakPtr<BrowserPluginGuest> opener_;
diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
index 42c748693d..209f43e5e5 100644
--- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
+++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
@@ -453,11 +453,11 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_EmbedderSameAfterNav) {
// does not happen and existing embedder doesn't change in web_contents.
GURL test_url_new(embedded_test_server()->GetURL(
"/browser_plugin_title_change.html"));
- const string16 expected_title = ASCIIToUTF16("done");
+ const base::string16 expected_title = ASCIIToUTF16("done");
content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
NavigateToURL(shell(), test_url_new);
VLOG(0) << "Start waiting for title";
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
VLOG(0) << "Done navigating to second page";
@@ -536,26 +536,26 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) {
// the page has successfully reloaded when it goes back to 'embedder'
// in the next step.
{
- const string16 expected_title = ASCIIToUTF16("modified");
+ const base::string16 expected_title = ASCIIToUTF16("modified");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
ExecuteSyncJSFunction(rvh,
base::StringPrintf("SetTitle('%s');", "modified"));
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
// Reload the embedder page, and verify that the reload was successful.
// Then navigate the guest to verify that the browser process does not crash.
{
- const string16 expected_title = ASCIIToUTF16("embedder");
+ const base::string16 expected_title = ASCIIToUTF16("embedder");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
test_embedder()->web_contents()->GetController().Reload(false);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
ExecuteSyncJSFunction(
@@ -618,7 +618,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) {
// This should trigger appropriate messages from the embedder to the guest,
// and end with a drop on the guest. The guest changes title when a drop
// happens.
- const string16 expected_title = ASCIIToUTF16("DROPPED");
+ const base::string16 expected_title = ASCIIToUTF16("DROPPED");
content::TitleWatcher title_watcher(test_guest()->web_contents(),
expected_title);
@@ -628,7 +628,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) {
blink::WebDragOperationEvery, 0);
rvh->DragTargetDrop(gfx::Point(end_x, end_y), gfx::Point(end_x, end_y), 0);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
@@ -650,7 +650,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) {
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
- const string16 expected_title = ASCIIToUTF16("main guest");
+ const base::string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
@@ -661,7 +661,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) {
// The title will be updated to "main guest" at the last stage of the
// process described above.
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
}
@@ -678,7 +678,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
- const string16 expected_title = ASCIIToUTF16("main guest");
+ const base::string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
@@ -687,7 +687,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
// The title will be updated to "main guest" at the last stage of the
// process described above.
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
{
@@ -703,7 +703,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
base::StringPrintf(
"CreateChildFrame('%s');", test_url.spec().c_str()));
- string16 actual_title = ready_watcher.WaitAndGetTitle();
+ base::string16 actual_title = ready_watcher.WaitAndGetTitle();
EXPECT_EQ(ASCIIToUTF16("ready"), actual_title);
content::TitleWatcher iframe_watcher(test_embedder()->web_contents(),
@@ -810,4 +810,119 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DoNotCrashOnInvalidNavigation) {
EXPECT_TRUE(delegate->load_aborted_url().is_valid());
}
+
+// Tests involving the threaded compositor.
+class BrowserPluginThreadedCompositorTest : public BrowserPluginHostTest {
+ public:
+ BrowserPluginThreadedCompositorTest() {}
+ virtual ~BrowserPluginThreadedCompositorTest() {}
+
+ protected:
+ virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
+ BrowserPluginHostTest::SetUpCommandLine(cmd);
+ cmd->AppendSwitch(switches::kEnableThreadedCompositing);
+
+ // http://crbug.com/327035
+ cmd->AppendSwitch(switches::kDisableDelegatedRenderer);
+ }
+};
+
+static void CompareSkBitmaps(const SkBitmap& expected_bitmap,
+ const SkBitmap& bitmap) {
+ EXPECT_EQ(expected_bitmap.width(), bitmap.width());
+ if (expected_bitmap.width() != bitmap.width())
+ return;
+ EXPECT_EQ(expected_bitmap.height(), bitmap.height());
+ if (expected_bitmap.height() != bitmap.height())
+ return;
+ EXPECT_EQ(expected_bitmap.config(), bitmap.config());
+ if (expected_bitmap.config() != bitmap.config())
+ return;
+
+ SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
+ SkAutoLockPixels bitmap_lock(bitmap);
+ int fails = 0;
+ const int kAllowableError = 2;
+ for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
+ for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
+ SkColor expected_color = expected_bitmap.getColor(i, j);
+ SkColor color = bitmap.getColor(i, j);
+ int expected_alpha = SkColorGetA(expected_color);
+ int alpha = SkColorGetA(color);
+ int expected_red = SkColorGetR(expected_color);
+ int red = SkColorGetR(color);
+ int expected_green = SkColorGetG(expected_color);
+ int green = SkColorGetG(color);
+ int expected_blue = SkColorGetB(expected_color);
+ int blue = SkColorGetB(color);
+ EXPECT_NEAR(expected_alpha, alpha, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_red, red, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_green, green, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_blue, blue, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ }
+ }
+ EXPECT_LT(fails, 10);
+}
+
+static void CompareSkBitmapAndRun(const base::Closure& callback,
+ const SkBitmap& expected_bitmap,
+ bool *result,
+ bool succeed,
+ const SkBitmap& bitmap) {
+ *result = succeed;
+ if (succeed)
+ CompareSkBitmaps(expected_bitmap, bitmap);
+ callback.Run();
+}
+
+// http://crbug.com/171744
+#if defined(OS_MACOSX)
+#define MAYBE_GetBackingStore DISABLED_GetBackingStore
+#else
+#define MAYBE_GetBackingStore GetBackingStore
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserPluginThreadedCompositorTest,
+ MAYBE_GetBackingStore) {
+ const char kEmbedderURL[] = "/browser_plugin_embedder.html";
+ const char kHTMLForGuest[] =
+ "data:text/html,<html><style>body { background-color: red; }</style>"
+ "<body></body></html>";
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true,
+ std::string("SetSize(50, 60);"));
+
+ WebContentsImpl* guest_contents = test_guest()->web_contents();
+ RenderWidgetHostImpl* guest_widget_host =
+ RenderWidgetHostImpl::From(guest_contents->GetRenderViewHost());
+
+ SkBitmap expected_bitmap;
+ expected_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 50, 60);
+ expected_bitmap.allocPixels();
+ expected_bitmap.eraseARGB(255, 255, 0, 0); // #f00
+ bool result = false;
+ while (!result) {
+ base::RunLoop loop;
+ guest_widget_host->CopyFromBackingStore(gfx::Rect(),
+ guest_widget_host->GetView()->GetViewBounds().size(),
+ base::Bind(&CompareSkBitmapAndRun, loop.QuitClosure(), expected_bitmap,
+ &result));
+ loop.Run();
+ }
+}
+
} // namespace content
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc b/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
index dc2db35119..59ae63555d 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
+++ b/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
@@ -20,9 +20,9 @@ void TestBrowserPluginGuestDelegate::ResetStates() {
void TestBrowserPluginGuestDelegate::AddMessageToConsole(
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
}
void TestBrowserPluginGuestDelegate::Close() {
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h b/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
index 910ff9f324..4bfae4c622 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
+++ b/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
@@ -22,9 +22,9 @@ class TestBrowserPluginGuestDelegate : public BrowserPluginGuestDelegate {
private:
// Overridden from BrowserPluginGuestDelegate:
virtual void AddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) OVERRIDE;
+ const base::string16& source_id) OVERRIDE;
virtual void Close() OVERRIDE;
virtual void GuestProcessGone(base::TerminationStatus status) OVERRIDE;
virtual bool HandleKeyboardEvent(
diff --git a/content/browser/browser_shutdown_profile_dumper.cc b/content/browser/browser_shutdown_profile_dumper.cc
index ebec936011..3e74e063b0 100644
--- a/content/browser/browser_shutdown_profile_dumper.cc
+++ b/content/browser/browser_shutdown_profile_dumper.cc
@@ -37,7 +37,7 @@ void BrowserShutdownProfileDumper::WriteTracesToDisc(
base::debug::TraceLog::GetInstance()->GetBufferPercentFull() <<
" full.";
DCHECK(!dump_file_);
- dump_file_ = file_util::OpenFile(file_name, "w+");
+ dump_file_ = base::OpenFile(file_name, "w+");
if (!IsFileValid()) {
LOG(ERROR) << "Failed to open performance trace file: " <<
file_name.value();
@@ -131,7 +131,7 @@ void BrowserShutdownProfileDumper::WriteChars(const char* chars, size_t size) {
void BrowserShutdownProfileDumper::CloseFile() {
if (!dump_file_)
return;
- file_util::CloseFile(dump_file_);
+ base::CloseFile(dump_file_);
dump_file_ = NULL;
}
diff --git a/content/browser/browser_url_handler_impl.cc b/content/browser/browser_url_handler_impl.cc
index 9a73afa5eb..05cc72df47 100644
--- a/content/browser/browser_url_handler_impl.cc
+++ b/content/browser/browser_url_handler_impl.cc
@@ -24,7 +24,7 @@ static bool HandleViewSource(GURL* url, BrowserContext* browser_context) {
// Bug 26129: limit view-source to view the content and not any
// other kind of 'active' url scheme like 'javascript' or 'data'.
static const char* const allowed_sub_schemes[] = {
- kHttpScheme, kHttpsScheme, chrome::kFtpScheme,
+ kHttpScheme, kHttpsScheme, kFtpScheme,
chrome::kChromeDevToolsScheme, chrome::kChromeUIScheme,
chrome::kFileScheme, chrome::kFileSystemScheme
};
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index 85ec83a4e3..0667964f3e 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -310,7 +310,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
// We know about these schemes and believe them to be safe.
RegisterWebSafeScheme(kHttpScheme);
RegisterWebSafeScheme(kHttpsScheme);
- RegisterWebSafeScheme(chrome::kFtpScheme);
+ RegisterWebSafeScheme(kFtpScheme);
RegisterWebSafeScheme(chrome::kDataScheme);
RegisterWebSafeScheme("feed");
RegisterWebSafeScheme(chrome::kBlobScheme);
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index 670848fa48..c4d51b3eb3 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -122,7 +122,7 @@ TEST_F(ChildProcessSecurityPolicyTest, IsWebSafeSchemeTest) {
EXPECT_TRUE(p->IsWebSafeScheme(kHttpScheme));
EXPECT_TRUE(p->IsWebSafeScheme(kHttpsScheme));
- EXPECT_TRUE(p->IsWebSafeScheme(chrome::kFtpScheme));
+ EXPECT_TRUE(p->IsWebSafeScheme(kFtpScheme));
EXPECT_TRUE(p->IsWebSafeScheme(chrome::kDataScheme));
EXPECT_TRUE(p->IsWebSafeScheme("feed"));
EXPECT_TRUE(p->IsWebSafeScheme(chrome::kBlobScheme));
diff --git a/content/browser/device_orientation/data_fetcher_impl_android.cc b/content/browser/device_orientation/data_fetcher_impl_android.cc
index 230507ee44..c103029f62 100644
--- a/content/browser/device_orientation/data_fetcher_impl_android.cc
+++ b/content/browser/device_orientation/data_fetcher_impl_android.cc
@@ -8,11 +8,20 @@
#include "base/android/jni_android.h"
#include "base/memory/singleton.h"
+#include "base/metrics/histogram.h"
#include "content/browser/device_orientation/inertial_sensor_consts.h"
#include "jni/DeviceMotionAndOrientation_jni.h"
using base::android::AttachCurrentThread;
+namespace {
+
+static void updateRotationVectorHistogram(bool value) {
+ UMA_HISTOGRAM_BOOLEAN("InertialSensor.RotationVectorAndroidAvailable", value);
+}
+
+}
+
namespace content {
DataFetcherImplAndroid::DataFetcherImplAndroid()
@@ -54,8 +63,10 @@ void DataFetcherImplAndroid::GotOrientation(
device_orientation_buffer_->data.hasGamma = true;
device_orientation_buffer_->seqlock.WriteEnd();
- if (!is_orientation_buffer_ready_)
+ if (!is_orientation_buffer_ready_) {
SetOrientationBufferReadyStatus(true);
+ updateRotationVectorHistogram(true);
+ }
}
void DataFetcherImplAndroid::GotAcceleration(
@@ -191,6 +202,15 @@ void DataFetcherImplAndroid::CheckMotionBufferReadyToRead() {
device_motion_buffer_->data.interval = kInertialSensorIntervalMillis;
device_motion_buffer_->seqlock.WriteEnd();
SetMotionBufferReadyStatus(true);
+
+ UMA_HISTOGRAM_BOOLEAN("InertialSensor.AccelerometerAndroidAvailable",
+ received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] > 0);
+ UMA_HISTOGRAM_BOOLEAN(
+ "InertialSensor.AccelerometerIncGravityAndroidAvailable",
+ received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY]
+ > 0);
+ UMA_HISTOGRAM_BOOLEAN("InertialSensor.GyroscopeAndroidAvailable",
+ received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] > 0);
}
}
@@ -233,6 +253,10 @@ bool DataFetcherImplAndroid::StartFetchingDeviceOrientationData(
// to start firing all-null events.
SetOrientationBufferReadyStatus(!success);
}
+
+ if (!success)
+ updateRotationVectorHistogram(false);
+
return success;
}
diff --git a/content/browser/devtools/browser_protocol.json b/content/browser/devtools/browser_protocol.json
index 029b7a0915..59e73c0c59 100644
--- a/content/browser/devtools/browser_protocol.json
+++ b/content/browser/devtools/browser_protocol.json
@@ -21,7 +21,7 @@
"type": "object",
"properties": [
{ "name": "devices", "type": "array", "items": { "$ref": "GPUDevice" }, "description": "The graphics devices on the system. Element 0 is the primary GPU." },
- { "name": "auxAttributes", "type": "object", "optional": "true", "description": "An optional dictionary of additional GPU related attributes." }
+ { "name": "auxAttributes", "type": "object", "optional": "true", "description": "An optional dictionary of additional GPU related attributes." },
{ "name": "featureStatus", "type": "object", "optional": "true", "description": "An optional dictionary of graphics features and their status." }
],
"description": "Provides information about the GPU(s) on the system."
@@ -42,7 +42,8 @@
"description": "Returns information about the system.",
"returns": [
{ "name": "info", "$ref": "SystemInfo", "description": "Information about the system." }
- ]
+ ],
+ "handlers": ["browser"]
}
]
}]
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc
index f223c6020c..aac9b6cbb9 100644
--- a/content/browser/devtools/devtools_manager_unittest.cc
+++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -7,7 +7,6 @@
#include "base/time/time.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/render_view_devtools_agent_host.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/view_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -16,6 +15,7 @@
#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/test/test_content_browser_client.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/content/browser/devtools/devtools_protocol_constants.cc b/content/browser/devtools/devtools_protocol_constants.cc
index ff0357b842..af5ecd1f58 100644
--- a/content/browser/devtools/devtools_protocol_constants.cc
+++ b/content/browser/devtools/devtools_protocol_constants.cc
@@ -2,206 +2,292 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// THIS FILE IS AUTOGENERATED.
+// If you need change something in this file, please see
+// protocol.json and browser_protocol.json
+
#include "content/browser/devtools/devtools_protocol_constants.h"
namespace content {
namespace devtools {
-const char kParamX[] = "x";
-const char kParamY[] = "y";
-const char kParamWidth[] = "width";
-const char kParamHeight[] = "height";
const char kResult[] = "result";
namespace DOM {
-
-namespace setFileInputFiles {
- const char kName[] = "DOM.setFileInputFiles";
- const char kParamFiles[] = "files";
-} // setFileInputFiles
-
-} // DOM
+ const char kName[] = "DOM";
+
+ namespace Rect {
+ const char kParamHeight[] = "height";
+ const char kParamWidth[] = "width";
+ const char kParamX[] = "x";
+ const char kParamY[] = "y";
+ } // Rect
+
+ namespace setFileInputFiles {
+ const char kName[] = "DOM.setFileInputFiles";
+ const char kParamFiles[] = "files";
+ const char kParamNodeId[] = "nodeId";
+ } // setFileInputFiles
+} // DOM
namespace Input {
-
-const char kParamType[] = "type";
-const char kParamModifiers[] = "modifiers";
-const char kParamTimestamp[] = "timestamp";
-const char kParamDeviceSpace[] = "deviceSpace";
-
-namespace dispatchMouseEvent {
- const char kName[] = "Input.dispatchMouseEvent";
- const char kParamButton[] = "button";
- const char kParamClickCount[] = "clickCount";
-} // dispatchMouseEvent
-
-namespace dispatchGestureEvent {
- const char kName[] = "Input.dispatchGestureEvent";
- const char kParamDeltaX[] = "deltaX";
- const char kParamDeltaY[] = "deltaY";
- const char kParamPinchScale[] = "pinchScale";
-} // dispatchGestureEvent
-
-} // Input
+ const char kName[] = "Input";
+
+ namespace dispatchGestureEvent {
+ const char kName[] = "Input.dispatchGestureEvent";
+ const char kParamDeltaX[] = "deltaX";
+ const char kParamDeltaY[] = "deltaY";
+ const char kParamPinchScale[] = "pinchScale";
+ const char kParamTimestamp[] = "timestamp";
+ const char kParamType[] = "type";
+ const char kParamX[] = "x";
+ const char kParamY[] = "y";
+
+ namespace Type {
+ const char kEnumPinchBegin[] = "pinchBegin";
+ const char kEnumPinchEnd[] = "pinchEnd";
+ const char kEnumPinchUpdate[] = "pinchUpdate";
+ const char kEnumScrollBegin[] = "scrollBegin";
+ const char kEnumScrollEnd[] = "scrollEnd";
+ const char kEnumScrollUpdate[] = "scrollUpdate";
+ const char kEnumTap[] = "tap";
+ const char kEnumTapDown[] = "tapDown";
+ } // Type
+ } // dispatchGestureEvent
+
+ namespace dispatchMouseEvent {
+ const char kName[] = "Input.dispatchMouseEvent";
+ const char kParamButton[] = "button";
+ const char kParamClickCount[] = "clickCount";
+ const char kParamDeviceSpace[] = "deviceSpace";
+ const char kParamModifiers[] = "modifiers";
+ const char kParamTimestamp[] = "timestamp";
+ const char kParamType[] = "type";
+ const char kParamX[] = "x";
+ const char kParamY[] = "y";
+
+ namespace Button {
+ const char kEnumLeft[] = "left";
+ const char kEnumMiddle[] = "middle";
+ const char kEnumNone[] = "none";
+ const char kEnumRight[] = "right";
+ } // Button
+
+ namespace Type {
+ const char kEnumMouseMoved[] = "mouseMoved";
+ const char kEnumMousePressed[] = "mousePressed";
+ const char kEnumMouseReleased[] = "mouseReleased";
+ } // Type
+ } // dispatchMouseEvent
+} // Input
namespace Inspector {
+ const char kName[] = "Inspector";
-namespace detached {
- const char kName[] = "Inspector.detached";
- const char kParamReason[] = "reason";
-} // detached
+ namespace detached {
+ const char kName[] = "Inspector.detached";
+ const char kParamReason[] = "reason";
+ } // detached
-namespace targetCrashed {
- const char kName[] = "Inspector.targetCrashed";
-} // targetCrashed
-
-} // Inspector
+ namespace targetCrashed {
+ const char kName[] = "Inspector.targetCrashed";
+ } // targetCrashed
+} // Inspector
namespace Page {
+ const char kName[] = "Page";
+
+ namespace NavigationEntry {
+ const char kParamId[] = "id";
+ const char kParamTitle[] = "title";
+ const char kParamUrl[] = "url";
+ } // NavigationEntry
+
+ namespace Quota {
+ const char kParamPersistent[] = "persistent";
+ const char kParamTemporary[] = "temporary";
+ } // Quota
+
+ namespace ScreencastFrameMetadata {
+ const char kParamDeviceScaleFactor[] = "deviceScaleFactor";
+ const char kParamOffsetBottom[] = "offsetBottom";
+ const char kParamOffsetTop[] = "offsetTop";
+ const char kParamPageScaleFactor[] = "pageScaleFactor";
+ const char kParamPageScaleFactorMax[] = "pageScaleFactorMax";
+ const char kParamPageScaleFactorMin[] = "pageScaleFactorMin";
+ const char kParamViewport[] = "viewport";
+ } // ScreencastFrameMetadata
+
+ namespace Usage {
+ const char kParamPersistent[] = "persistent";
+ const char kParamSyncable[] = "syncable";
+ const char kParamTemporary[] = "temporary";
+ } // Usage
+
+ namespace UsageItem {
+ const char kParamId[] = "id";
+ const char kParamValue[] = "value";
+
+ namespace Id {
+ const char kEnumAppcache[] = "appcache";
+ const char kEnumDatabase[] = "database";
+ const char kEnumFilesystem[] = "filesystem";
+ const char kEnumIndexeddatabase[] = "indexeddatabase";
+ } // Id
+ } // UsageItem
+
+ namespace canScreencast {
+ const char kName[] = "Page.canScreencast";
+ const char kResponseResult[] = "result";
+ } // canScreencast
+
+ namespace captureScreenshot {
+ const char kName[] = "Page.captureScreenshot";
+ const char kParamFormat[] = "format";
+ const char kParamMaxHeight[] = "maxHeight";
+ const char kParamMaxWidth[] = "maxWidth";
+ const char kParamQuality[] = "quality";
+ const char kResponseData[] = "data";
+ const char kResponseMetadata[] = "metadata";
+
+ namespace Format {
+ const char kEnumJpeg[] = "jpeg";
+ const char kEnumPng[] = "png";
+ } // Format
+ } // captureScreenshot
+
+ namespace disable {
+ const char kName[] = "Page.disable";
+ } // disable
+
+ namespace getNavigationHistory {
+ const char kName[] = "Page.getNavigationHistory";
+ const char kResponseCurrentIndex[] = "currentIndex";
+ const char kResponseEntries[] = "entries";
+ } // getNavigationHistory
+
+ namespace handleJavaScriptDialog {
+ const char kName[] = "Page.handleJavaScriptDialog";
+ const char kParamAccept[] = "accept";
+ const char kParamPromptText[] = "promptText";
+ } // handleJavaScriptDialog
+
+ namespace navigate {
+ const char kName[] = "Page.navigate";
+ const char kParamUrl[] = "url";
+ } // navigate
+
+ namespace navigateToHistoryEntry {
+ const char kName[] = "Page.navigateToHistoryEntry";
+ const char kParamEntryId[] = "entryId";
+ } // navigateToHistoryEntry
+
+ namespace queryUsageAndQuota {
+ const char kName[] = "Page.queryUsageAndQuota";
+ const char kParamSecurityOrigin[] = "securityOrigin";
+ const char kResponseQuota[] = "quota";
+ const char kResponseUsage[] = "usage";
+ } // queryUsageAndQuota
+
+ namespace reload {
+ const char kName[] = "Page.reload";
+ const char kParamIgnoreCache[] = "ignoreCache";
+ const char kParamScriptPreprocessor[] = "scriptPreprocessor";
+ const char kParamScriptToEvaluateOnLoad[] = "scriptToEvaluateOnLoad";
+ } // reload
+
+ namespace screencastFrame {
+ const char kName[] = "Page.screencastFrame";
+ const char kParamData[] = "data";
+ const char kParamMetadata[] = "metadata";
+ } // screencastFrame
+
+ namespace screencastVisibilityChanged {
+ const char kName[] = "Page.screencastVisibilityChanged";
+ const char kParamVisible[] = "visible";
+ } // screencastVisibilityChanged
+
+ namespace startScreencast {
+ const char kName[] = "Page.startScreencast";
+ const char kParamFormat[] = "format";
+ const char kParamMaxHeight[] = "maxHeight";
+ const char kParamMaxWidth[] = "maxWidth";
+ const char kParamQuality[] = "quality";
+
+ namespace Format {
+ const char kEnumJpeg[] = "jpeg";
+ const char kEnumPng[] = "png";
+ } // Format
+ } // startScreencast
+
+ namespace stopScreencast {
+ const char kName[] = "Page.stopScreencast";
+ } // stopScreencast
+} // Page
-const char kData[] = "data";
-const char kMetadata[] = "metadata";
-const char kParamDeviceScaleFactor[] = "deviceScaleFactor";
-const char kParamPageScaleFactor[] = "pageScaleFactor";
-const char kParamPageScaleFactorMin[] = "pageScaleFactorMin";
-const char kParamPageScaleFactorMax[] = "pageScaleFactorMax";
-const char kParamOffsetBottom[] = "offsetBottom";
-const char kParamOffsetTop[] = "offsetTop";
-const char kParamViewport[] = "viewport";
-
-namespace disable {
- const char kName[] = "Page.disable";
-} // disable
-
-namespace handleJavaScriptDialog {
- const char kName[] = "Page.handleJavaScriptDialog";
- const char kParamAccept[] = "accept";
- const char kParamPromptText[] = "promptText";
-} // handleJavaScriptDialog
-
-namespace navigate {
- const char kName[] = "Page.navigate";
- const char kParamUrl[] = "url";
-} // navigate
-
-namespace reload {
- const char kName[] = "Page.reload";
-} // reload
-
-namespace getNavigationHistory {
- const char kName[] = "Page.getNavigationHistory";
- const char kResponseCurrentIndex[] = "currentIndex";
- const char kResponseEntries[] = "entries";
- const char kResponseEntryId[] = "id";
- const char kResponseEntryURL[] = "url";
- const char kResponseEntryTitle[] = "title";
-} // getNavigationHistory
-
-namespace navigateToHistoryEntry {
- const char kName[] = "Page.navigateToHistoryEntry";
- const char kParamEntryId[] = "entryId";
-} // navigateToHistoryEntry
-
-namespace captureScreenshot {
- const char kName[] = "Page.captureScreenshot";
- const char kParamFormat[] = "format";
- const char kParamQuality[] = "quality";
- const char kParamMaxWidth[] = "maxWidth";
- const char kParamMaxHeight[] = "maxHeight";
-} // captureScreenshot
-
-namespace canScreencast {
- const char kName[] = "Page.canScreencast";
-} // canScreencast
-
-namespace startScreencast {
- const char kName[] = "Page.startScreencast";
-} // startScreencast
-
-namespace stopScreencast {
- const char kName[] = "Page.stopScreencast";
-} // stopScreencast
-
-namespace screencastFrame {
- const char kName[] = "Page.screencastFrame";
-} // screencastFrame
-
-namespace queryUsageAndQuota {
- const char kName[] = "Page.queryUsageAndQuota";
- const char kParamSecurityOrigin[] = "securityOrigin";
- extern const char kResponseQuota[] = "quota";
- extern const char kResponseUsage[] = "usage";
-} // queryUsageAndQuota
-
-namespace Quota {
- extern const char kItemTemporary[] = "temporary";
- extern const char kItemPersistent[] = "persistent";
-} // Quota
-
-namespace Usage {
- extern const char kItemTemporary[] = "temporary";
- extern const char kItemPersistent[] = "persistent";
- extern const char kItemSyncable[] = "syncable";
-} // Usage
-
-namespace UsageItem {
- namespace ID {
- extern const char kFilesystem[] = "filesystem";
- extern const char kDatabase[] = "database";
- extern const char kAppcache[] = "appcache";
- extern const char kIndexedDatabase[] = "indexeddatabase";
- } // ID
- extern const char kItemID[] = "id";
- extern const char kItemValue[] = "value";
-} // UsageItem
-
-namespace screencastVisibilityChanged {
- const char kName[] = "Page.screencastVisibilityChanged";
- const char kParamVisible[] = "visible";
-} // screencastVisibilityChanged
-
-} // Page
-
-namespace Worker {
-
-namespace disconnectedFromWorker {
- const char kName[] = "Worker.disconnectedFromWorker";
-} // disconnectedFromWorker
+namespace SystemInfo {
+ const char kName[] = "SystemInfo";
-} // Worker
+ namespace GPUDevice {
+ const char kParamDeviceId[] = "deviceId";
+ const char kParamDeviceString[] = "deviceString";
+ const char kParamVendorId[] = "vendorId";
+ const char kParamVendorString[] = "vendorString";
+ } // GPUDevice
+
+ namespace GPUInfo {
+ const char kParamAuxAttributes[] = "auxAttributes";
+ const char kParamDevices[] = "devices";
+ const char kParamFeatureStatus[] = "featureStatus";
+ } // GPUInfo
+
+ namespace SystemInfo {
+ const char kParamGpu[] = "gpu";
+ const char kParamModelName[] = "modelName";
+ } // SystemInfo
+
+ namespace getInfo {
+ const char kName[] = "SystemInfo.getInfo";
+ const char kResponseInfo[] = "info";
+ } // getInfo
+} // SystemInfo
namespace Tracing {
const char kName[] = "Tracing";
-namespace start {
- const char kName[] = "Tracing.start";
- const char kCategories[] = "categories";
- const char kTraceOptions[] = "trace-options";
-} // start
+ namespace dataCollected {
+ const char kName[] = "Tracing.dataCollected";
+ const char kParamValue[] = "value";
+ } // dataCollected
-namespace end {
- const char kName[] = "Tracing.end";
-}
+ namespace end {
+ const char kName[] = "Tracing.end";
+ } // end
-namespace tracingComplete {
- const char kName[] = "Tracing.tracingComplete";
-}
+ namespace start {
+ const char kName[] = "Tracing.start";
+ const char kParamCategories[] = "categories";
+ const char kParamOptions[] = "options";
+ } // start
-namespace dataCollected {
- const char kName[] = "Tracing.dataCollected";
- const char kValue[] = "value";
-}
+ namespace tracingComplete {
+ const char kName[] = "Tracing.tracingComplete";
+ } // tracingComplete
+} // Tracing
-} // Tracing
+namespace Worker {
+ const char kName[] = "Worker";
-namespace SystemInfo {
- const char kName[] = "SystemInfo";
+ namespace disconnectFromWorker {
+ const char kName[] = "Worker.disconnectFromWorker";
+ const char kParamWorkerId[] = "workerId";
+ } // disconnectFromWorker
+
+ namespace disconnectedFromWorker {
+ const char kName[] = "Worker.disconnectedFromWorker";
+ } // disconnectedFromWorker
+} // Worker
-namespace getInfo {
- const char kName[] = "SystemInfo.getInfo";
-} // getInfo
-} // SystemInfo
} // devtools
} // content
-
diff --git a/content/browser/devtools/devtools_protocol_constants.h b/content/browser/devtools/devtools_protocol_constants.h
index e24304a540..8ed159bc0d 100644
--- a/content/browser/devtools/devtools_protocol_constants.h
+++ b/content/browser/devtools/devtools_protocol_constants.h
@@ -5,211 +5,290 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTSH_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTSH_
-// The constants in this file should be used instead manually constructing
-// strings passed to and from DevTools protocol.
-//
-// There is a plan to generate this file from inspector.json automatically.
-// Until then please feel free to add the constants here as needed.
+// THIS FILE IS AUTOGENERATED.
+// If you need change something in this file, please see
+// protocol.json and browser_protocol.json
namespace content {
namespace devtools {
-extern const char kParamX[];
-extern const char kParamY[];
-extern const char kParamWidth[];
-extern const char kParamHeight[];
extern const char kResult[];
namespace DOM {
+ extern const char kName[];
+
+ namespace Rect {
+ extern const char kParamHeight[];
+ extern const char kParamWidth[];
+ extern const char kParamX[];
+ extern const char kParamY[];
+ } // Rect
namespace setFileInputFiles {
extern const char kName[];
extern const char kParamFiles[];
- } // setFileInputFiles
-
-} // DOM
+ extern const char kParamNodeId[];
+ } // setFileInputFiles
+} // DOM
namespace Input {
-
- extern const char kParamType[];
- extern const char kParamModifiers[];
- extern const char kParamTimestamp[];
- extern const char kParamDeviceSpace[];
-
- namespace dispatchMouseEvent {
- extern const char kName[];
- extern const char kParamX[];
- extern const char kParamY[];
- extern const char kParamButton[];
- extern const char kParamClickCount[];
- } // dispatchMouseEvent
+ extern const char kName[];
namespace dispatchGestureEvent {
extern const char kName[];
extern const char kParamDeltaX[];
extern const char kParamDeltaY[];
extern const char kParamPinchScale[];
- } // dispatchGestureEvent
+ extern const char kParamTimestamp[];
+ extern const char kParamType[];
+ extern const char kParamX[];
+ extern const char kParamY[];
+
+ namespace Type {
+ extern const char kEnumPinchBegin[];
+ extern const char kEnumPinchEnd[];
+ extern const char kEnumPinchUpdate[];
+ extern const char kEnumScrollBegin[];
+ extern const char kEnumScrollEnd[];
+ extern const char kEnumScrollUpdate[];
+ extern const char kEnumTap[];
+ extern const char kEnumTapDown[];
+ } // Type
+ } // dispatchGestureEvent
+
+ namespace dispatchMouseEvent {
+ extern const char kName[];
+ extern const char kParamButton[];
+ extern const char kParamClickCount[];
+ extern const char kParamDeviceSpace[];
+ extern const char kParamModifiers[];
+ extern const char kParamTimestamp[];
+ extern const char kParamType[];
+ extern const char kParamX[];
+ extern const char kParamY[];
-} // Input
+ namespace Button {
+ extern const char kEnumLeft[];
+ extern const char kEnumMiddle[];
+ extern const char kEnumNone[];
+ extern const char kEnumRight[];
+ } // Button
+
+ namespace Type {
+ extern const char kEnumMouseMoved[];
+ extern const char kEnumMousePressed[];
+ extern const char kEnumMouseReleased[];
+ } // Type
+ } // dispatchMouseEvent
+} // Input
namespace Inspector {
+ extern const char kName[];
namespace detached {
extern const char kName[];
extern const char kParamReason[];
- } // detached
+ } // detached
namespace targetCrashed {
extern const char kName[];
- } // targetCrashed
-
-} // Inspector
+ } // targetCrashed
+} // Inspector
namespace Page {
+ extern const char kName[];
- extern const char kData[];
- extern const char kMetadata[];
- extern const char kParamDeviceScaleFactor[];
- extern const char kParamPageScaleFactor[];
- extern const char kParamPageScaleFactorMin[];
- extern const char kParamPageScaleFactorMax[];
- extern const char kParamOffsetBottom[];
- extern const char kParamOffsetTop[];
- extern const char kParamViewport[];
+ namespace NavigationEntry {
+ extern const char kParamId[];
+ extern const char kParamTitle[];
+ extern const char kParamUrl[];
+ } // NavigationEntry
- namespace disable {
- extern const char kName[];
- } // disable
+ namespace Quota {
+ extern const char kParamPersistent[];
+ extern const char kParamTemporary[];
+ } // Quota
+
+ namespace ScreencastFrameMetadata {
+ extern const char kParamDeviceScaleFactor[];
+ extern const char kParamOffsetBottom[];
+ extern const char kParamOffsetTop[];
+ extern const char kParamPageScaleFactor[];
+ extern const char kParamPageScaleFactorMax[];
+ extern const char kParamPageScaleFactorMin[];
+ extern const char kParamViewport[];
+ } // ScreencastFrameMetadata
- namespace handleJavaScriptDialog {
+ namespace Usage {
+ extern const char kParamPersistent[];
+ extern const char kParamSyncable[];
+ extern const char kParamTemporary[];
+ } // Usage
+
+ namespace UsageItem {
+ extern const char kParamId[];
+ extern const char kParamValue[];
+
+ namespace Id {
+ extern const char kEnumAppcache[];
+ extern const char kEnumDatabase[];
+ extern const char kEnumFilesystem[];
+ extern const char kEnumIndexeddatabase[];
+ } // Id
+ } // UsageItem
+
+ namespace canScreencast {
extern const char kName[];
- extern const char kParamAccept[];
- extern const char kParamPromptText[];
- } // handleJavaScriptDialog
+ extern const char kResponseResult[];
+ } // canScreencast
- namespace navigate {
+ namespace captureScreenshot {
extern const char kName[];
- extern const char kParamUrl[];
- } // navigate
+ extern const char kParamFormat[];
+ extern const char kParamMaxHeight[];
+ extern const char kParamMaxWidth[];
+ extern const char kParamQuality[];
+ extern const char kResponseData[];
+ extern const char kResponseMetadata[];
- namespace reload {
+ namespace Format {
+ extern const char kEnumJpeg[];
+ extern const char kEnumPng[];
+ } // Format
+ } // captureScreenshot
+
+ namespace disable {
extern const char kName[];
- } // reload
+ } // disable
namespace getNavigationHistory {
extern const char kName[];
extern const char kResponseCurrentIndex[];
extern const char kResponseEntries[];
- extern const char kResponseEntryId[];
- extern const char kResponseEntryURL[];
- extern const char kResponseEntryTitle[];
- } // getNavigationHistory
+ } // getNavigationHistory
- namespace navigateToHistoryEntry {
+ namespace handleJavaScriptDialog {
extern const char kName[];
- extern const char kParamEntryId[];
- } // navigateToHistoryEntry
+ extern const char kParamAccept[];
+ extern const char kParamPromptText[];
+ } // handleJavaScriptDialog
- namespace captureScreenshot {
+ namespace navigate {
extern const char kName[];
- extern const char kParamFormat[];
- extern const char kParamQuality[];
- extern const char kParamMaxWidth[];
- extern const char kParamMaxHeight[];
- } // captureScreenshot
+ extern const char kParamUrl[];
+ } // navigate
- namespace canScreencast {
+ namespace navigateToHistoryEntry {
extern const char kName[];
- } // canScreencast
+ extern const char kParamEntryId[];
+ } // navigateToHistoryEntry
- namespace startScreencast {
+ namespace queryUsageAndQuota {
extern const char kName[];
- } // startScreencast
+ extern const char kParamSecurityOrigin[];
+ extern const char kResponseQuota[];
+ extern const char kResponseUsage[];
+ } // queryUsageAndQuota
- namespace stopScreencast {
+ namespace reload {
extern const char kName[];
- } // stopScreencast
+ extern const char kParamIgnoreCache[];
+ extern const char kParamScriptPreprocessor[];
+ extern const char kParamScriptToEvaluateOnLoad[];
+ } // reload
namespace screencastFrame {
extern const char kName[];
- } // screencastFrame
+ extern const char kParamData[];
+ extern const char kParamMetadata[];
+ } // screencastFrame
- namespace queryUsageAndQuota {
+ namespace screencastVisibilityChanged {
extern const char kName[];
- extern const char kParamSecurityOrigin[];
- extern const char kResponseQuota[];
- extern const char kResponseUsage[];
- } // queryUsageAndQuota
+ extern const char kParamVisible[];
+ } // screencastVisibilityChanged
- namespace Quota {
- extern const char kItemTemporary[];
- extern const char kItemPersistent[];
- } // Quota
+ namespace startScreencast {
+ extern const char kName[];
+ extern const char kParamFormat[];
+ extern const char kParamMaxHeight[];
+ extern const char kParamMaxWidth[];
+ extern const char kParamQuality[];
- namespace Usage {
- extern const char kItemTemporary[];
- extern const char kItemPersistent[];
- extern const char kItemSyncable[];
- } // Usage
+ namespace Format {
+ extern const char kEnumJpeg[];
+ extern const char kEnumPng[];
+ } // Format
+ } // startScreencast
- namespace UsageItem {
- namespace ID {
- extern const char kFilesystem[];
- extern const char kDatabase[];
- extern const char kAppcache[];
- extern const char kIndexedDatabase[];
- } // ID
- extern const char kItemID[];
- extern const char kItemValue[];
- } // UsageItem
+ namespace stopScreencast {
+ extern const char kName[];
+ } // stopScreencast
+} // Page
- namespace screencastVisibilityChanged {
+namespace SystemInfo {
+ extern const char kName[];
+
+ namespace GPUDevice {
+ extern const char kParamDeviceId[];
+ extern const char kParamDeviceString[];
+ extern const char kParamVendorId[];
+ extern const char kParamVendorString[];
+ } // GPUDevice
+
+ namespace GPUInfo {
+ extern const char kParamAuxAttributes[];
+ extern const char kParamDevices[];
+ extern const char kParamFeatureStatus[];
+ } // GPUInfo
+
+ namespace SystemInfo {
+ extern const char kParamGpu[];
+ extern const char kParamModelName[];
+ } // SystemInfo
+
+ namespace getInfo {
extern const char kName[];
- extern const char kParamVisible[];
- } // screencastVisibilityChanged
-} // Page
+ extern const char kResponseInfo[];
+ } // getInfo
+} // SystemInfo
namespace Tracing {
extern const char kName[];
- namespace start {
+ namespace dataCollected {
extern const char kName[];
- extern const char kCategories[];
- extern const char kTraceOptions[];
- } // start
+ extern const char kParamValue[];
+ } // dataCollected
namespace end {
extern const char kName[];
- }
+ } // end
- namespace tracingComplete {
+ namespace start {
extern const char kName[];
- }
+ extern const char kParamCategories[];
+ extern const char kParamOptions[];
+ } // start
- namespace dataCollected {
+ namespace tracingComplete {
extern const char kName[];
- extern const char kValue[];
- }
-
-} // Tracing
+ } // tracingComplete
+} // Tracing
namespace Worker {
+ extern const char kName[];
- namespace disconnectedFromWorker {
+ namespace disconnectFromWorker {
extern const char kName[];
- } // disconnectedFromWorker
-
-} // Worker
+ extern const char kParamWorkerId[];
+ } // disconnectFromWorker
+ namespace disconnectedFromWorker {
+ extern const char kName[];
+ } // disconnectedFromWorker
+} // Worker
-namespace SystemInfo {
- extern const char kName[];
-
-namespace getInfo {
- extern const char kName[];
-} // getInfo
-} // SystemInfo
} // devtools
} // content
diff --git a/content/browser/devtools/devtools_resources.gyp b/content/browser/devtools/devtools_resources.gyp
index 19b114c9df..30b4220945 100644
--- a/content/browser/devtools/devtools_resources.gyp
+++ b/content/browser/devtools/devtools_resources.gyp
@@ -8,7 +8,7 @@
'target_name': 'devtools_resources',
'type': 'none',
'dependencies': [
- '../../../third_party/WebKit/Source/devtools/devtools.gyp:generate_devtools_grd',
+ '../../../third_party/WebKit/public/blink_devtools.gyp:blink_generate_devtools_grd',
],
'variables': {
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/webkit',
diff --git a/content/browser/devtools/devtools_resources.target.darwin-arm.mk b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
index a0fc8f39ed..cb142bb384 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-arm.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.darwin-mips.mk b/content/browser/devtools/devtools_resources.target.darwin-mips.mk
index a0fc8f39ed..cb142bb384 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-mips.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-mips.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.darwin-x86.mk b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
index a0fc8f39ed..f176b4becf 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-x86.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D use_webaudio_enable_message -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.linux-arm.mk b/content/browser/devtools/devtools_resources.target.linux-arm.mk
index a0fc8f39ed..cb142bb384 100644
--- a/content/browser/devtools/devtools_resources.target.linux-arm.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-arm.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.linux-mips.mk b/content/browser/devtools/devtools_resources.target.linux-mips.mk
index a0fc8f39ed..cb142bb384 100644
--- a/content/browser/devtools/devtools_resources.target.linux-mips.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-mips.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_resources.target.linux-x86.mk b/content/browser/devtools/devtools_resources.target.linux-x86.mk
index a0fc8f39ed..f176b4becf 100644
--- a/content/browser/devtools/devtools_resources.target.linux-x86.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-x86.mk
@@ -12,7 +12,7 @@ gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared)
# Make sure our deps are built first.
GYP_TARGET_DEPENDENCIES := \
- $(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_generate_devtools_grd_gyp)/generate_devtools_grd.stamp
+ $(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_generate_devtools_grd_gyp)/blink_generate_devtools_grd.stamp
### Rules for action "devtools_resources":
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
@@ -21,7 +21,7 @@ $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_inte
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/clique_unittest.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/c_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_writer_base_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/rc_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html_unittest.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/gather/txt_unittest.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grd_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/grit_runner_unittest.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/lazy_re_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/base_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/include_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/io_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/message_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/misc_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/structure_unittest.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/pseudo_unittest.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/tclib_unittest.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/build_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc_unittest.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb_unittest.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/util_unittest.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader_unittest.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from $(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd ($@)"
- $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D use_concatenated_impulse_responses
+ $(hide)cd $(gyp_local_path)/content/browser/devtools; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../../../tools/grit/grit.py -i "$(gyp_shared_intermediate_dir)/devtools/devtools_resources.grd" build -f GRIT_DIR/../gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D "SHARED_INTERMEDIATE_DIR=$(gyp_shared_intermediate_dir)" -D _chromium -E "CHROMIUM_BUILD=chromium" -D use_webaudio_enable_message -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses
$(gyp_shared_intermediate_dir)/webkit/devtools_resources.pak: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources_map.cc: $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h ;
diff --git a/content/browser/devtools/devtools_tracing_handler.cc b/content/browser/devtools/devtools_tracing_handler.cc
index 0657b8e48d..e9f6cf10b2 100644
--- a/content/browser/devtools/devtools_tracing_handler.cc
+++ b/content/browser/devtools/devtools_tracing_handler.cc
@@ -6,14 +6,18 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/location.h"
+#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_http_handler_impl.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
-#include "content/public/browser/trace_controller.h"
-#include "content/public/browser/trace_subscriber.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/tracing_controller.h"
namespace content {
@@ -23,10 +27,23 @@ const char kRecordUntilFull[] = "record-until-full";
const char kRecordContinuously[] = "record-continuously";
const char kEnableSampling[] = "enable-sampling";
+void ReadFile(
+ const base::FilePath& path,
+ const base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
+ callback) {
+ std::string trace_data;
+ if (!base::ReadFileToString(path, &trace_data))
+ LOG(ERROR) << "Failed to read file: " << path.value();
+ base::DeleteFile(path, false);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, make_scoped_refptr(
+ base::RefCountedString::TakeString(&trace_data))));
+}
+
} // namespace
DevToolsTracingHandler::DevToolsTracingHandler()
- : is_running_(false) {
+ : weak_factory_(this) {
RegisterCommandHandler(devtools::Tracing::start::kName,
base::Bind(&DevToolsTracingHandler::OnStart,
base::Unretained(this)));
@@ -38,28 +55,60 @@ DevToolsTracingHandler::DevToolsTracingHandler()
DevToolsTracingHandler::~DevToolsTracingHandler() {
}
-void DevToolsTracingHandler::OnEndTracingComplete() {
- is_running_ = false;
+void DevToolsTracingHandler::BeginReadingRecordingResult(
+ const base::FilePath& path) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ReadFile, path,
+ base::Bind(&DevToolsTracingHandler::ReadRecordingResult,
+ weak_factory_.GetWeakPtr())));
+}
+
+void DevToolsTracingHandler::ReadRecordingResult(
+ const scoped_refptr<base::RefCountedString>& trace_data) {
+ if (trace_data->data().size()) {
+ scoped_ptr<base::Value> trace_value(base::JSONReader::Read(
+ trace_data->data()));
+ DictionaryValue* dictionary = NULL;
+ bool ok = trace_value->GetAsDictionary(&dictionary);
+ DCHECK(ok);
+ ListValue* list = NULL;
+ ok = dictionary->GetList("traceEvents", &list);
+ DCHECK(ok);
+ std::string buffer;
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ std::string item;
+ base::Value* item_value;
+ list->Get(i, &item_value);
+ base::JSONWriter::Write(item_value, &item);
+ if (buffer.size())
+ buffer.append(",");
+ buffer.append(item);
+ if (i % 1000 == 0) {
+ OnTraceDataCollected(buffer);
+ buffer.clear();
+ }
+ }
+ if (buffer.size())
+ OnTraceDataCollected(buffer);
+ }
+
SendNotification(devtools::Tracing::tracingComplete::kName, NULL);
}
void DevToolsTracingHandler::OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& trace_fragment) {
- if (is_running_) {
- // Hand-craft protocol notification message so we can substitute JSON
- // that we already got as string as a bare object, not a quoted string.
- std::string message = base::StringPrintf(
- "{ \"method\": \"%s\", \"params\": { \"%s\": [ %s ] } }",
- devtools::Tracing::dataCollected::kName,
- devtools::Tracing::dataCollected::kValue,
- trace_fragment->data().c_str());
- SendRawMessage(message);
- }
+ const std::string& trace_fragment) {
+ // Hand-craft protocol notification message so we can substitute JSON
+ // that we already got as string as a bare object, not a quoted string.
+ std::string message = base::StringPrintf(
+ "{ \"method\": \"%s\", \"params\": { \"%s\": [ %s ] } }",
+ devtools::Tracing::dataCollected::kName,
+ devtools::Tracing::dataCollected::kParamValue,
+ trace_fragment.c_str());
+ SendRawMessage(message);
}
-// Note, if you add more options here you also need to update:
-// base/debug/trace_event_impl:TraceOptionsFromString
-base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString(
+TracingController::Options DevToolsTracingHandler::TraceOptionsFromString(
const std::string& options) {
std::vector<std::string> split;
std::vector<std::string>::iterator iter;
@@ -68,18 +117,14 @@ base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString(
base::SplitString(options, ',', &split);
for (iter = split.begin(); iter != split.end(); ++iter) {
if (*iter == kRecordUntilFull) {
- ret |= base::debug::TraceLog::RECORD_UNTIL_FULL;
+ ret &= ~TracingController::RECORD_CONTINUOUSLY;
} else if (*iter == kRecordContinuously) {
- ret |= base::debug::TraceLog::RECORD_CONTINUOUSLY;
+ ret |= TracingController::RECORD_CONTINUOUSLY;
} else if (*iter == kEnableSampling) {
- ret |= base::debug::TraceLog::ENABLE_SAMPLING;
+ ret |= TracingController::ENABLE_SAMPLING;
}
}
- if (!(ret & base::debug::TraceLog::RECORD_UNTIL_FULL) &&
- !(ret & base::debug::TraceLog::RECORD_CONTINUOUSLY))
- ret |= base::debug::TraceLog::RECORD_UNTIL_FULL;
-
- return static_cast<base::debug::TraceLog::Options>(ret);
+ return static_cast<TracingController::Options>(ret);
}
scoped_refptr<DevToolsProtocol::Response>
@@ -88,25 +133,28 @@ DevToolsTracingHandler::OnStart(
std::string categories;
base::DictionaryValue* params = command->params();
if (params)
- params->GetString(devtools::Tracing::start::kCategories, &categories);
+ params->GetString(devtools::Tracing::start::kParamCategories, &categories);
- base::debug::TraceLog::Options options =
- base::debug::TraceLog::RECORD_UNTIL_FULL;
- if (params && params->HasKey(devtools::Tracing::start::kTraceOptions)) {
+ TracingController::Options options = TracingController::DEFAULT_OPTIONS;
+ if (params && params->HasKey(devtools::Tracing::start::kParamOptions)) {
std::string options_param;
- params->GetString(devtools::Tracing::start::kTraceOptions, &options_param);
+ params->GetString(devtools::Tracing::start::kParamOptions, &options_param);
options = TraceOptionsFromString(options_param);
}
- TraceController::GetInstance()->BeginTracing(this, categories, options);
- is_running_ = true;
+ TracingController::GetInstance()->EnableRecording(
+ categories, options,
+ TracingController::EnableRecordingDoneCallback());
return command->SuccessResponse(NULL);
}
scoped_refptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnEnd(
scoped_refptr<DevToolsProtocol::Command> command) {
- TraceController::GetInstance()->EndTracingAsync(this);
+ TracingController::GetInstance()->DisableRecording(
+ base::FilePath(),
+ base::Bind(&DevToolsTracingHandler::BeginReadingRecordingResult,
+ weak_factory_.GetWeakPtr()));
return command->SuccessResponse(NULL);
}
diff --git a/content/browser/devtools/devtools_tracing_handler.h b/content/browser/devtools/devtools_tracing_handler.h
index 43cd6150ed..b551e7579e 100644
--- a/content/browser/devtools/devtools_tracing_handler.h
+++ b/content/browser/devtools/devtools_tracing_handler.h
@@ -5,36 +5,36 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
-#include "base/debug/trace_event.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/devtools_protocol.h"
-#include "content/public/browser/trace_subscriber.h"
+#include "content/public/browser/tracing_controller.h"
+
+namespace base {
+class RefCountedString;
+}
namespace content {
// This class bridges DevTools remote debugging server with the trace
// infrastructure.
-class DevToolsTracingHandler
- : public TraceSubscriber,
- public DevToolsProtocol::Handler {
+class DevToolsTracingHandler : public DevToolsProtocol::Handler {
public:
DevToolsTracingHandler();
virtual ~DevToolsTracingHandler();
- // TraceSubscriber:
- virtual void OnEndTracingComplete() OVERRIDE;;
- virtual void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& trace_fragment) OVERRIDE;
-
private:
+ void BeginReadingRecordingResult(const base::FilePath& path);
+ void ReadRecordingResult(const scoped_refptr<base::RefCountedString>& result);
+ void OnTraceDataCollected(const std::string& trace_fragment);
+
scoped_refptr<DevToolsProtocol::Response> OnStart(
scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> OnEnd(
scoped_refptr<DevToolsProtocol::Command> command);
- base::debug::TraceLog::Options TraceOptionsFromString(
- const std::string& options);
+ TracingController::Options TraceOptionsFromString(const std::string& options);
- bool is_running_;
+ base::WeakPtrFactory<DevToolsTracingHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DevToolsTracingHandler);
};
diff --git a/content/browser/devtools/render_view_devtools_agent_host.cc b/content/browser/devtools/render_view_devtools_agent_host.cc
index b2777783ea..8e0348b1c5 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.cc
+++ b/content/browser/devtools/render_view_devtools_agent_host.cc
@@ -353,7 +353,17 @@ bool RenderViewDevToolsAgentHost::OnMessageReceived(
void RenderViewDevToolsAgentHost::OnSwapCompositorFrame(
const IPC::Message& message) {
- overrides_handler_->OnSwapCompositorFrame(message);
+ ViewHostMsg_SwapCompositorFrame::Param param;
+ if (!ViewHostMsg_SwapCompositorFrame::Read(&message, &param))
+ return;
+ overrides_handler_->OnSwapCompositorFrame(param.b.metadata);
+}
+
+void RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame(
+ const cc::CompositorFrameMetadata& frame_metadata) {
+ if (!render_view_host_)
+ return;
+ overrides_handler_->OnSwapCompositorFrame(frame_metadata);
}
void RenderViewDevToolsAgentHost::OnSaveAgentRuntimeState(
diff --git a/content/browser/devtools/render_view_devtools_agent_host.h b/content/browser/devtools/render_view_devtools_agent_host.h
index 4313e2ae2c..e7034008c8 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.h
+++ b/content/browser/devtools/render_view_devtools_agent_host.h
@@ -16,6 +16,10 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
+namespace cc {
+class CompositorFrameMetadata;
+}
+
namespace content {
class DevToolsTracingHandler;
@@ -38,6 +42,9 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
RenderViewHost* render_view_host() { return render_view_host_; }
+ void SynchronousSwapCompositorFrame(
+ const cc::CompositorFrameMetadata& frame_metadata);
+
private:
friend class DevToolsAgentHost;
diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc
index 2a99b3a3dc..4901f34cc1 100644
--- a/content/browser/devtools/renderer_overrides_handler.cc
+++ b/content/browser/devtools/renderer_overrides_handler.cc
@@ -63,7 +63,7 @@ static int kCaptureRetryLimit = 2;
void ParseGenericInputParams(base::DictionaryValue* params,
WebInputEvent* event) {
int modifiers = 0;
- if (params->GetInteger(devtools::Input::kParamModifiers,
+ if (params->GetInteger(devtools::Input::dispatchMouseEvent::kParamModifiers,
&modifiers)) {
if (modifiers & 1)
event->modifiers |= WebInputEvent::AltKey;
@@ -75,7 +75,7 @@ void ParseGenericInputParams(base::DictionaryValue* params,
event->modifiers |= WebInputEvent::ShiftKey;
}
- params->GetDouble(devtools::Input::kParamTimestamp,
+ params->GetDouble(devtools::Input::dispatchMouseEvent::kParamTimestamp,
&event->timeStampSeconds);
}
@@ -163,11 +163,8 @@ void RendererOverridesHandler::OnClientDetached() {
}
void RendererOverridesHandler::OnSwapCompositorFrame(
- const IPC::Message& message) {
- ViewHostMsg_SwapCompositorFrame::Param param;
- if (!ViewHostMsg_SwapCompositorFrame::Read(&message, &param))
- return;
- last_compositor_frame_metadata_ = param.b.metadata;
+ const cc::CompositorFrameMetadata& frame_metadata) {
+ last_compositor_frame_metadata_ = frame_metadata;
if (screencast_command_)
InnerSwapCompositorFrame();
@@ -293,8 +290,8 @@ RendererOverridesHandler::PageHandleJavaScriptDialog(
bool accept;
if (!params || !params->GetBoolean(paramAccept, &accept))
return command->InvalidParamResponse(paramAccept);
- string16 prompt_override;
- string16* prompt_override_ptr = &prompt_override;
+ base::string16 prompt_override;
+ base::string16* prompt_override_ptr = &prompt_override;
if (!params || !params->GetString(
devtools::Page::handleJavaScriptDialog::kParamPromptText,
prompt_override_ptr)) {
@@ -375,13 +372,13 @@ RendererOverridesHandler::PageGetNavigationHistory(
const NavigationEntry* entry = controller.GetEntryAtIndex(i);
base::DictionaryValue* entry_value = new base::DictionaryValue();
entry_value->SetInteger(
- devtools::Page::getNavigationHistory::kResponseEntryId,
+ devtools::Page::NavigationEntry::kParamId,
entry->GetUniqueID());
entry_value->SetString(
- devtools::Page::getNavigationHistory::kResponseEntryURL,
+ devtools::Page::NavigationEntry::kParamUrl,
entry->GetURL().spec());
entry_value->SetString(
- devtools::Page::getNavigationHistory::kResponseEntryTitle,
+ devtools::Page::NavigationEntry::kParamTitle,
entry->GetTitle());
entries->Append(entry_value);
}
@@ -446,16 +443,13 @@ RendererOverridesHandler::PageCaptureScreenshot(
&png,
gfx::Rect(snapshot_size))) {
std::string base64_data;
- bool success = base::Base64Encode(
+ base::Base64Encode(
base::StringPiece(reinterpret_cast<char*>(&*png.begin()), png.size()),
&base64_data);
- if (success) {
- base::DictionaryValue* result = new base::DictionaryValue();
- result->SetString(
- devtools::Page::kData, base64_data);
- return command->SuccessResponse(result);
- }
- return command->InternalErrorResponse("Unable to base64encode screenshot");
+ base::DictionaryValue* result = new base::DictionaryValue();
+ result->SetString(
+ devtools::Page::captureScreenshot::kResponseData, base64_data);
+ return command->SuccessResponse(result);
}
// Fallback to copying from compositing surface.
@@ -475,10 +469,7 @@ RendererOverridesHandler::PageCanScreencast(
scoped_refptr<DevToolsProtocol::Command> command) {
base::DictionaryValue* result = new base::DictionaryValue();
#if defined(OS_ANDROID)
- // Android WebView does not support Screencast.
- std::string product = GetContentClient()->GetProduct();
- bool isChrome = product.find("Chrome/") == 0;
- result->SetBoolean(devtools::kResult, isChrome);
+ result->SetBoolean(devtools::kResult, true);
#else
result->SetBoolean(devtools::kResult, false);
#endif // defined(OS_ANDROID)
@@ -559,50 +550,56 @@ void RendererOverridesHandler::ScreenshotCaptured(
}
std::string base_64_data;
- if (!base::Base64Encode(base::StringPiece(
- reinterpret_cast<char*>(&data[0]),
- data.size()),
- &base_64_data)) {
- if (command) {
- SendAsyncResponse(
- command->InternalErrorResponse("Unable to base64 encode"));
- }
- return;
- }
+ base::Base64Encode(
+ base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()),
+ &base_64_data);
base::DictionaryValue* response = new base::DictionaryValue();
- response->SetString(devtools::Page::kData, base_64_data);
+ response->SetString(devtools::Page::screencastFrame::kParamData,
+ base_64_data);
// Consider metadata empty in case it has no device scale factor.
if (metadata.device_scale_factor != 0) {
base::DictionaryValue* response_metadata = new base::DictionaryValue();
- response_metadata->SetDouble(devtools::Page::kParamDeviceScaleFactor,
- metadata.device_scale_factor);
- response_metadata->SetDouble(devtools::Page::kParamPageScaleFactor,
- metadata.page_scale_factor);
- response_metadata->SetDouble(devtools::Page::kParamPageScaleFactorMin,
- metadata.min_page_scale_factor);
- response_metadata->SetDouble(devtools::Page::kParamPageScaleFactorMax,
- metadata.max_page_scale_factor);
- response_metadata->SetDouble(devtools::Page::kParamOffsetTop,
- metadata.location_bar_content_translation.y());
- response_metadata->SetDouble(devtools::Page::kParamOffsetBottom,
- metadata.overdraw_bottom_height);
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamDeviceScaleFactor,
+ metadata.device_scale_factor);
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamPageScaleFactor,
+ metadata.page_scale_factor);
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamPageScaleFactorMin,
+ metadata.min_page_scale_factor);
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamPageScaleFactorMax,
+ metadata.max_page_scale_factor);
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamOffsetTop,
+ metadata.location_bar_content_translation.y());
+ response_metadata->SetDouble(
+ devtools::Page::ScreencastFrameMetadata::kParamOffsetBottom,
+ metadata.overdraw_bottom_height);
base::DictionaryValue* viewport = new base::DictionaryValue();
- viewport->SetDouble(devtools::kParamX, metadata.root_scroll_offset.x());
- viewport->SetDouble(devtools::kParamY, metadata.root_scroll_offset.y());
- viewport->SetDouble(devtools::kParamWidth, metadata.viewport_size.width());
- viewport->SetDouble(devtools::kParamHeight,
+ viewport->SetDouble(devtools::DOM::Rect::kParamX,
+ metadata.root_scroll_offset.x());
+ viewport->SetDouble(devtools::DOM::Rect::kParamY,
+ metadata.root_scroll_offset.y());
+ viewport->SetDouble(devtools::DOM::Rect::kParamWidth,
+ metadata.viewport_size.width());
+ viewport->SetDouble(devtools::DOM::Rect::kParamHeight,
metadata.viewport_size.height());
- response_metadata->Set(devtools::Page::kParamViewport, viewport);
+ response_metadata->Set(
+ devtools::Page::ScreencastFrameMetadata::kParamViewport, viewport);
- // Temporarily duplicate properties to refactor API smoothly.
- // TODO(dzvorygin): remove after refactor.
- response->MergeDictionary(response_metadata);
-
- response->Set(devtools::Page::kMetadata, response_metadata);
+ if (command) {
+ response->Set(devtools::Page::captureScreenshot::kResponseMetadata,
+ response_metadata);
+ } else {
+ response->Set(devtools::Page::screencastFrame::kParamMetadata,
+ response_metadata);
+ }
}
if (command) {
@@ -641,8 +638,8 @@ void DidGetHostUsage(
const base::Closure& barrier,
int64 value) {
base::DictionaryValue* usage_item = new base::DictionaryValue;
- usage_item->SetString(devtools::Page::UsageItem::kItemID, client_id);
- usage_item->SetDouble(devtools::Page::UsageItem::kItemValue, value);
+ usage_item->SetString(devtools::Page::UsageItem::kParamId, client_id);
+ usage_item->SetDouble(devtools::Page::UsageItem::kParamValue, value);
list->Append(usage_item);
barrier.Run();
}
@@ -673,11 +670,11 @@ void DidGetUsageAndQuotaForWebApps(
std::string GetStorageTypeName(quota::StorageType type) {
switch (type) {
case quota::kStorageTypeTemporary:
- return devtools::Page::Usage::kItemTemporary;
+ return devtools::Page::Usage::kParamTemporary;
case quota::kStorageTypePersistent:
- return devtools::Page::Usage::kItemPersistent;
+ return devtools::Page::Usage::kParamPersistent;
case quota::kStorageTypeSyncable:
- return devtools::Page::Usage::kItemSyncable;
+ return devtools::Page::Usage::kParamSyncable;
case quota::kStorageTypeQuotaNotManaged:
case quota::kStorageTypeUnknown:
NOTREACHED();
@@ -688,13 +685,13 @@ std::string GetStorageTypeName(quota::StorageType type) {
std::string GetQuotaClientName(quota::QuotaClient::ID id) {
switch (id) {
case quota::QuotaClient::kFileSystem:
- return devtools::Page::UsageItem::ID::kFilesystem;
+ return devtools::Page::UsageItem::Id::kEnumFilesystem;
case quota::QuotaClient::kDatabase:
- return devtools::Page::UsageItem::ID::kDatabase;
+ return devtools::Page::UsageItem::Id::kEnumDatabase;
case quota::QuotaClient::kAppcache:
- return devtools::Page::UsageItem::ID::kAppcache;
+ return devtools::Page::UsageItem::Id::kEnumAppcache;
case quota::QuotaClient::kIndexedDatabase:
- return devtools::Page::UsageItem::ID::kIndexedDatabase;
+ return devtools::Page::UsageItem::Id::kEnumIndexeddatabase;
default:
NOTREACHED();
return "";
@@ -743,12 +740,12 @@ void QueryUsageAndQuotaOnIOThread(
security_origin,
quota::kStorageTypeTemporary,
base::Bind(&DidGetUsageAndQuotaForWebApps, quota_raw_ptr,
- std::string(devtools::Page::Quota::kItemTemporary), barrier));
+ std::string(devtools::Page::Quota::kParamTemporary), barrier));
quota_manager->GetPersistentHostQuota(
host,
base::Bind(&DidGetQuotaValue, quota_raw_ptr,
- std::string(devtools::Page::Quota::kItemPersistent),
+ std::string(devtools::Page::Quota::kParamPersistent),
barrier));
for (size_t i = 0; i != arraysize(kQuotaClients); i++) {
@@ -829,8 +826,9 @@ RendererOverridesHandler::InputDispatchMouseEvent(
return NULL;
bool device_space = false;
- if (!params->GetBoolean(devtools::Input::kParamDeviceSpace,
- &device_space) ||
+ if (!params->GetBoolean(
+ devtools::Input::dispatchMouseEvent::kParamDeviceSpace,
+ &device_space) ||
!device_space) {
return NULL;
}
@@ -840,13 +838,16 @@ RendererOverridesHandler::InputDispatchMouseEvent(
ParseGenericInputParams(params, &mouse_event);
std::string type;
- if (params->GetString(devtools::Input::kParamType,
+ if (params->GetString(devtools::Input::dispatchMouseEvent::kParamType,
&type)) {
- if (type == "mousePressed")
+ if (type ==
+ devtools::Input::dispatchMouseEvent::Type::kEnumMousePressed)
mouse_event.type = WebInputEvent::MouseDown;
- else if (type == "mouseReleased")
+ else if (type ==
+ devtools::Input::dispatchMouseEvent::Type::kEnumMouseReleased)
mouse_event.type = WebInputEvent::MouseUp;
- else if (type == "mouseMoved")
+ else if (type ==
+ devtools::Input::dispatchMouseEvent::Type::kEnumMouseMoved)
mouse_event.type = WebInputEvent::MouseMove;
else
return NULL;
@@ -854,8 +855,10 @@ RendererOverridesHandler::InputDispatchMouseEvent(
return NULL;
}
- if (!params->GetInteger(devtools::kParamX, &mouse_event.x) ||
- !params->GetInteger(devtools::kParamY, &mouse_event.y)) {
+ if (!params->GetInteger(devtools::Input::dispatchMouseEvent::kParamX,
+ &mouse_event.x) ||
+ !params->GetInteger(devtools::Input::dispatchMouseEvent::kParamY,
+ &mouse_event.y)) {
return NULL;
}
@@ -905,23 +908,31 @@ RendererOverridesHandler::InputDispatchGestureEvent(
ParseGenericInputParams(params, &event);
std::string type;
- if (params->GetString(devtools::Input::kParamType,
+ if (params->GetString(devtools::Input::dispatchGestureEvent::kParamType,
&type)) {
- if (type == "scrollBegin")
+ if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumScrollBegin)
event.type = WebInputEvent::GestureScrollBegin;
- else if (type == "scrollUpdate")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumScrollUpdate)
event.type = WebInputEvent::GestureScrollUpdate;
- else if (type == "scrollEnd")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumScrollEnd)
event.type = WebInputEvent::GestureScrollEnd;
- else if (type == "tapDown")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumTapDown)
event.type = WebInputEvent::GestureTapDown;
- else if (type == "tap")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumTap)
event.type = WebInputEvent::GestureTap;
- else if (type == "pinchBegin")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumPinchBegin)
event.type = WebInputEvent::GesturePinchBegin;
- else if (type == "pinchUpdate")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumPinchUpdate)
event.type = WebInputEvent::GesturePinchUpdate;
- else if (type == "pinchEnd")
+ else if (type ==
+ devtools::Input::dispatchGestureEvent::Type::kEnumPinchEnd)
event.type = WebInputEvent::GesturePinchEnd;
else
return NULL;
@@ -929,8 +940,10 @@ RendererOverridesHandler::InputDispatchGestureEvent(
return NULL;
}
- if (!params->GetInteger(devtools::kParamX, &event.x) ||
- !params->GetInteger(devtools::kParamY, &event.y)) {
+ if (!params->GetInteger(devtools::Input::dispatchGestureEvent::kParamX,
+ &event.x) ||
+ !params->GetInteger(devtools::Input::dispatchGestureEvent::kParamY,
+ &event.y)) {
return NULL;
}
event.globalX = event.x;
diff --git a/content/browser/devtools/renderer_overrides_handler.h b/content/browser/devtools/renderer_overrides_handler.h
index 2556c9ae54..cce32767c3 100644
--- a/content/browser/devtools/renderer_overrides_handler.h
+++ b/content/browser/devtools/renderer_overrides_handler.h
@@ -35,7 +35,7 @@ class CONTENT_EXPORT RendererOverridesHandler
virtual ~RendererOverridesHandler();
void OnClientDetached();
- void OnSwapCompositorFrame(const IPC::Message& message);
+ void OnSwapCompositorFrame(const cc::CompositorFrameMetadata& frame_metadata);
void OnVisibilityChanged(bool visible);
private:
diff --git a/content/browser/devtools/worker_devtools_manager.cc b/content/browser/devtools/worker_devtools_manager.cc
index f08523b998..f0608815f3 100644
--- a/content/browser/devtools/worker_devtools_manager.cc
+++ b/content/browser/devtools/worker_devtools_manager.cc
@@ -52,13 +52,15 @@ base::LazyInstance<AgentHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER;
} // namespace
struct WorkerDevToolsManager::TerminatedInspectedWorker {
- TerminatedInspectedWorker(WorkerId id, const GURL& url, const string16& name)
+ TerminatedInspectedWorker(WorkerId id,
+ const GURL& url,
+ const base::string16& name)
: old_worker_id(id),
worker_url(url),
worker_name(name) {}
WorkerId old_worker_id;
GURL worker_url;
- string16 worker_name;
+ base::string16 worker_name;
};
@@ -202,7 +204,7 @@ class WorkerDevToolsManager::DetachedClientHosts {
struct WorkerDevToolsManager::InspectedWorker {
InspectedWorker(WorkerProcessHost* host, int route_id, const GURL& url,
- const string16& name)
+ const base::string16& name)
: host(host),
route_id(route_id),
worker_url(url),
@@ -210,7 +212,7 @@ struct WorkerDevToolsManager::InspectedWorker {
WorkerProcessHost* const host;
int const route_id;
GURL worker_url;
- string16 worker_name;
+ base::string16 worker_name;
};
// static
diff --git a/content/browser/dom_storage/dom_storage_context_impl.cc b/content/browser/dom_storage/dom_storage_context_impl.cc
index 44c4242c53..2c31bd627b 100644
--- a/content/browser/dom_storage/dom_storage_context_impl.cc
+++ b/content/browser/dom_storage/dom_storage_context_impl.cc
@@ -68,7 +68,7 @@ DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
if (found == namespaces_.end()) {
if (namespace_id == kLocalStorageNamespaceId) {
if (!localstorage_directory_.empty()) {
- if (!file_util::CreateDirectory(localstorage_directory_)) {
+ if (!base::CreateDirectory(localstorage_directory_)) {
LOG(ERROR) << "Failed to create 'Local Storage' directory,"
" falling back to in-memory only.";
localstorage_directory_ = base::FilePath();
diff --git a/content/browser/dom_storage/dom_storage_message_filter.cc b/content/browser/dom_storage/dom_storage_message_filter.cc
index 3ab972cd72..fbc3880abb 100644
--- a/content/browser/dom_storage/dom_storage_message_filter.cc
+++ b/content/browser/dom_storage/dom_storage_message_filter.cc
@@ -116,8 +116,8 @@ void DOMStorageMessageFilter::OnLoadStorageArea(int connection_id,
}
void DOMStorageMessageFilter::OnSetItem(
- int connection_id, const string16& key,
- const string16& value, const GURL& page_url) {
+ int connection_id, const base::string16& key,
+ const base::string16& value, const GURL& page_url) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(0, connection_dispatching_message_for_);
base::AutoReset<int> auto_reset(&connection_dispatching_message_for_,
@@ -129,20 +129,20 @@ void DOMStorageMessageFilter::OnSetItem(
}
void DOMStorageMessageFilter::OnLogGetItem(
- int connection_id, const string16& key,
+ int connection_id, const base::string16& key,
const base::NullableString16& value) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
host_->LogGetAreaItem(connection_id, key, value);
}
void DOMStorageMessageFilter::OnRemoveItem(
- int connection_id, const string16& key,
+ int connection_id, const base::string16& key,
const GURL& page_url) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(0, connection_dispatching_message_for_);
base::AutoReset<int> auto_reset(&connection_dispatching_message_for_,
connection_id);
- string16 not_used;
+ base::string16 not_used;
host_->RemoveAreaItem(connection_id, key, page_url, &not_used);
Send(new DOMStorageMsg_AsyncOperationComplete(true));
}
@@ -163,8 +163,8 @@ void DOMStorageMessageFilter::OnFlushMessages() {
void DOMStorageMessageFilter::OnDOMStorageItemSet(
const DOMStorageArea* area,
- const string16& key,
- const string16& new_value,
+ const base::string16& key,
+ const base::string16& new_value,
const base::NullableString16& old_value,
const GURL& page_url) {
SendDOMStorageEvent(area, page_url,
@@ -175,8 +175,8 @@ void DOMStorageMessageFilter::OnDOMStorageItemSet(
void DOMStorageMessageFilter::OnDOMStorageItemRemoved(
const DOMStorageArea* area,
- const string16& key,
- const string16& old_value,
+ const base::string16& key,
+ const base::string16& old_value,
const GURL& page_url) {
SendDOMStorageEvent(area, page_url,
base::NullableString16(key, false),
diff --git a/content/browser/dom_storage/dom_storage_message_filter.h b/content/browser/dom_storage/dom_storage_message_filter.h
index a2670ef37a..3c82418842 100644
--- a/content/browser/dom_storage/dom_storage_message_filter.h
+++ b/content/browser/dom_storage/dom_storage_message_filter.h
@@ -53,11 +53,11 @@ class DOMStorageMessageFilter
void OnCloseStorageArea(int connection_id);
void OnLoadStorageArea(int connection_id, DOMStorageValuesMap* map,
bool* send_log_get_messages);
- void OnSetItem(int connection_id, const string16& key,
- const string16& value, const GURL& page_url);
- void OnLogGetItem(int connection_id, const string16& key,
+ void OnSetItem(int connection_id, const base::string16& key,
+ const base::string16& value, const GURL& page_url);
+ void OnLogGetItem(int connection_id, const base::string16& key,
const base::NullableString16& value);
- void OnRemoveItem(int connection_id, const string16& key,
+ void OnRemoveItem(int connection_id, const base::string16& key,
const GURL& page_url);
void OnClear(int connection_id, const GURL& page_url);
void OnFlushMessages();
@@ -66,14 +66,14 @@ class DOMStorageMessageFilter
// sends events back to our renderer process.
virtual void OnDOMStorageItemSet(
const DOMStorageArea* area,
- const string16& key,
- const string16& new_value,
+ const base::string16& key,
+ const base::string16& new_value,
const base::NullableString16& old_value,
const GURL& page_url) OVERRIDE;
virtual void OnDOMStorageItemRemoved(
const DOMStorageArea* area,
- const string16& key,
- const string16& old_value,
+ const base::string16& key,
+ const base::string16& old_value,
const GURL& page_url) OVERRIDE;
virtual void OnDOMStorageAreaCleared(
const DOMStorageArea* area,
diff --git a/content/browser/dom_storage/session_storage_database.cc b/content/browser/dom_storage/session_storage_database.cc
index bac3df7a67..7b8dcd0bf0 100644
--- a/content/browser/dom_storage/session_storage_database.cc
+++ b/content/browser/dom_storage/session_storage_database.cc
@@ -280,8 +280,7 @@ bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
return true;
if (!create_if_needed &&
- (!base::PathExists(file_path_) ||
- file_util::IsDirectoryEmpty(file_path_))) {
+ (!base::PathExists(file_path_) || base::IsDirectoryEmpty(file_path_))) {
// If the directory doesn't exist already and we haven't been asked to
// create a file on disk, then we don't bother opening the database. This
// means we wait until we absolutely need to put something onto disk before
diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc
index 90ab485c36..1de3e842dd 100644
--- a/content/browser/download/base_file.cc
+++ b/content/browser/download/base_file.cc
@@ -82,8 +82,8 @@ DownloadInterruptReason BaseFile::Initialize(
// |initial_directory| can still be empty if ContentBrowserClient returned
// an empty path for the downloads directory.
if ((initial_directory.empty() ||
- !file_util::CreateTemporaryFileInDir(initial_directory, &temp_file)) &&
- !file_util::CreateTemporaryFile(&temp_file)) {
+ !base::CreateTemporaryFileInDir(initial_directory, &temp_file)) &&
+ !base::CreateTemporaryFile(&temp_file)) {
return LogInterruptReason("Unable to create", 0,
DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
}
@@ -165,7 +165,7 @@ DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) {
net::NetLog::TYPE_DOWNLOAD_FILE_RENAMED,
base::Bind(&FileRenamedNetLogCallback, &full_path_, &new_path));
Close();
- file_util::CreateDirectory(new_path.DirName());
+ base::CreateDirectory(new_path.DirName());
// A simple rename wouldn't work here since we want the file to have
// permissions / security descriptors that makes sense in the new directory.
diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc
index b82b0a8ab7..4ab0c2ae8f 100644
--- a/content/browser/download/base_file_unittest.cc
+++ b/content/browser/download/base_file_unittest.cc
@@ -464,7 +464,7 @@ TEST_F(BaseFileTest, RenameWithError) {
// TestDir is a subdirectory in |temp_dir_| that we will make read-only so
// that the rename will fail.
base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir"));
- ASSERT_TRUE(file_util::CreateDirectory(test_dir));
+ ASSERT_TRUE(base::CreateDirectory(test_dir));
base::FilePath new_path(test_dir.AppendASCII("TestFile"));
EXPECT_FALSE(base::PathExists(new_path));
@@ -482,7 +482,7 @@ TEST_F(BaseFileTest, RenameWithError) {
// Write data to the file multiple times.
TEST_F(BaseFileTest, MultipleWritesWithError) {
base::FilePath path;
- ASSERT_TRUE(file_util::CreateTemporaryFile(&path));
+ ASSERT_TRUE(base::CreateTemporaryFile(&path));
// Create a new file stream. scoped_ptr takes ownership and passes it to
// BaseFile; we use the pointer anyway and rely on the BaseFile not
// deleting the MockFileStream until the BaseFile is reset.
@@ -623,8 +623,7 @@ TEST_F(BaseFileTest, CreatedInDefaultDirectory) {
// be a string-wise match to base_file_->full_path().DirName() even though
// they are in the same directory.
base::FilePath temp_file;
- ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
- &temp_file));
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file));
ASSERT_FALSE(temp_file.empty());
EXPECT_STREQ(temp_file.DirName().value().c_str(),
base_file_->full_path().DirName().value().c_str());
diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc
index dcc0e424bd..141808685f 100644
--- a/content/browser/download/download_file_unittest.cc
+++ b/content/browser/download/download_file_unittest.cc
@@ -195,7 +195,7 @@ class DownloadFileTest : public testing::Test {
void VerifyStreamAndSize() {
::testing::Mock::VerifyAndClearExpectations(input_stream_);
int64 size;
- EXPECT_TRUE(file_util::GetFileSize(download_file_->FullPath(), &size));
+ EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size));
EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size));
}
@@ -461,7 +461,7 @@ TEST_F(DownloadFileTest, RenameError) {
// Create a subdirectory.
base::FilePath tempdir(
initial_path.DirName().Append(FILE_PATH_LITERAL("tempdir")));
- ASSERT_TRUE(file_util::CreateDirectory(tempdir));
+ ASSERT_TRUE(base::CreateDirectory(tempdir));
base::FilePath target_path(tempdir.Append(initial_path.BaseName()));
// Targets
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index ea0f305a5a..35825d32a9 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -413,7 +413,7 @@ void DownloadManagerImpl::StartDownloadWithId(
file_factory_->CreateFile(
info->save_info.Pass(), default_download_directory,
info->url(), info->referrer_url,
- delegate_->GenerateFileHash(),
+ delegate_ && delegate_->GenerateFileHash(),
stream.Pass(), download->GetBoundNetLog(),
download->DestinationObserverAsWeakPtr()));
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index aecded1262..3afc41ad5a 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -120,7 +120,7 @@ class MockDownloadItemImpl : public DownloadItemImpl {
MOCK_CONST_METHOD0(CurrentSpeed, int64());
MOCK_CONST_METHOD0(PercentComplete, int());
MOCK_CONST_METHOD0(AllDataSaved, bool());
- MOCK_CONST_METHOD1(MatchesQuery, bool(const string16& query));
+ MOCK_CONST_METHOD1(MatchesQuery, bool(const base::string16& query));
MOCK_CONST_METHOD0(IsDone, bool());
MOCK_CONST_METHOD0(GetFullPath, const base::FilePath&());
MOCK_CONST_METHOD0(GetTargetFilePath, const base::FilePath&());
diff --git a/content/browser/download/drag_download_file.h b/content/browser/download/drag_download_file.h
index 41fdf6224e..c281d977d8 100644
--- a/content/browser/download/drag_download_file.h
+++ b/content/browser/download/drag_download_file.h
@@ -17,7 +17,6 @@
#include "content/public/common/referrer.h"
#include "net/base/file_stream.h"
#include "ui/base/dragdrop/download_file_interface.h"
-#include "ui/base/ui_export.h"
#include "url/gurl.h"
namespace net {
diff --git a/content/browser/download/drag_download_util.cc b/content/browser/download/drag_download_util.cc
index 41bff06dd2..0850c3ba08 100644
--- a/content/browser/download/drag_download_util.cc
+++ b/content/browser/download/drag_download_util.cc
@@ -23,18 +23,18 @@ using net::FileStream;
namespace content {
-bool ParseDownloadMetadata(const string16& metadata,
- string16* mime_type,
+bool ParseDownloadMetadata(const base::string16& metadata,
+ base::string16* mime_type,
base::FilePath* file_name,
GURL* url) {
const char16 separator = L':';
size_t mime_type_end_pos = metadata.find(separator);
- if (mime_type_end_pos == string16::npos)
+ if (mime_type_end_pos == base::string16::npos)
return false;
size_t file_name_end_pos = metadata.find(separator, mime_type_end_pos + 1);
- if (file_name_end_pos == string16::npos)
+ if (file_name_end_pos == base::string16::npos)
return false;
GURL parsed_url = GURL(metadata.substr(file_name_end_pos + 1));
@@ -44,7 +44,7 @@ bool ParseDownloadMetadata(const string16& metadata,
if (mime_type)
*mime_type = metadata.substr(0, mime_type_end_pos);
if (file_name) {
- string16 file_name_str = metadata.substr(
+ base::string16 file_name_str = metadata.substr(
mime_type_end_pos + 1, file_name_end_pos - mime_type_end_pos - 1);
#if defined(OS_WIN)
*file_name = base::FilePath(file_name_str);
@@ -70,7 +70,7 @@ FileStream* CreateFileStreamForDrop(base::FilePath* file_path,
new_file_path = *file_path;
} else {
#if defined(OS_WIN)
- string16 suffix = ASCIIToUTF16("-") + base::IntToString16(seq);
+ base::string16 suffix = ASCIIToUTF16("-") + base::IntToString16(seq);
#else
std::string suffix = std::string("-") + base::IntToString(seq);
#endif
diff --git a/content/browser/download/drag_download_util.h b/content/browser/download/drag_download_util.h
index 8b58f4840e..ca266efa62 100644
--- a/content/browser/download/drag_download_util.h
+++ b/content/browser/download/drag_download_util.h
@@ -32,8 +32,8 @@ namespace content {
// appropriately.
// For example, we can have
// text/plain:example.txt:http://example.com/example.txt
-bool ParseDownloadMetadata(const string16& metadata,
- string16* mime_type,
+bool ParseDownloadMetadata(const base::string16& metadata,
+ base::string16* mime_type,
base::FilePath* file_name,
GURL* url);
diff --git a/content/browser/download/file_metadata_unittest_linux.cc b/content/browser/download/file_metadata_unittest_linux.cc
index 4f223519c4..96db264647 100644
--- a/content/browser/download/file_metadata_unittest_linux.cc
+++ b/content/browser/download/file_metadata_unittest_linux.cc
@@ -52,8 +52,7 @@ class FileMetadataLinuxTest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
- &test_file_));
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &test_file_));
int result = setxattr(test_file_.value().c_str(),
"user.test", "test", 4, 0);
is_xattr_supported_ = (!result) || (errno != ENOTSUP);
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc
index 6e790135bc..11a08519e2 100644
--- a/content/browser/download/mhtml_generation_browsertest.cc
+++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -66,7 +66,7 @@ IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, GenerateMHTML) {
// Make sure the actual generated file has some contents.
int64 file_size;
- ASSERT_TRUE(file_util::GetFileSize(path, &file_size));
+ ASSERT_TRUE(base::GetFileSize(path, &file_size));
EXPECT_GT(file_size, 100);
}
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc
index 442c28e102..85651b7709 100644
--- a/content/browser/download/save_file_manager.cc
+++ b/content/browser/download/save_file_manager.cc
@@ -482,7 +482,7 @@ void SaveFileManager::RenameAllFiles(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!resource_dir.empty() && !base::PathExists(resource_dir))
- file_util::CreateDirectory(resource_dir);
+ base::CreateDirectory(resource_dir);
for (FinalNameList::const_iterator i = final_names.begin();
i != final_names.end(); ++i) {
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 2fc68dff55..5961e6bf58 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -519,7 +519,7 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
if (ordinal_number > (kMaxFileOrdinalNumber - 1)) {
// Use a random file from temporary file.
base::FilePath temp_file;
- file_util::CreateTemporaryFile(&temp_file);
+ base::CreateTemporaryFile(&temp_file);
file_name = temp_file.RemoveExtension().BaseName().value();
// Get safe pure file name.
if (!GetSafePureFileName(saved_main_directory_path_,
@@ -1347,7 +1347,7 @@ void SavePackage::CreateDirectoryOnFileThread(
if (!skip_dir_check && !base::DirectoryExists(website_save_dir)) {
// If the default download dir doesn't exist, create it.
if (!base::DirectoryExists(download_save_dir)) {
- bool res = file_util::CreateDirectory(download_save_dir);
+ bool res = base::CreateDirectory(download_save_dir);
DCHECK(res);
}
save_dir = download_save_dir;
diff --git a/content/browser/download/save_package.h b/content/browser/download/save_package.h
index 939002e1ee..1ab429e16b 100644
--- a/content/browser/download/save_package.h
+++ b/content/browser/download/save_package.h
@@ -279,7 +279,7 @@ class CONTENT_EXPORT SavePackage
base::FilePath saved_main_directory_path_;
// The title of the page the user wants to save.
- string16 title_;
+ base::string16 title_;
// Used to calculate package download speed (in files per second).
base::TimeTicks start_tick_;
diff --git a/content/browser/download/save_package_unittest.cc b/content/browser/download/save_package_unittest.cc
index c0aa3f8862..47fd1b4668 100644
--- a/content/browser/download/save_package_unittest.cc
+++ b/content/browser/download/save_package_unittest.cc
@@ -10,8 +10,8 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/download/save_package.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/test/net/url_request_mock_http_job.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -346,7 +346,7 @@ TEST_F(SavePackageTest, MAYBE_TestEnsureMimeExtension) {
static const struct SuggestedSaveNameTestCase {
const char* page_url;
- const string16 page_title;
+ const base::string16 page_title;
const base::FilePath::CharType* expected_name;
bool ensure_html_extension;
} kSuggestedSaveNames[] = {
diff --git a/content/browser/fileapi/blob_url_request_job_unittest.cc b/content/browser/fileapi/blob_url_request_job_unittest.cc
index 607bb10566..a09456b607 100644
--- a/content/browser/fileapi/blob_url_request_job_unittest.cc
+++ b/content/browser/fileapi/blob_url_request_job_unittest.cc
@@ -146,7 +146,7 @@ class BlobURLRequestJobTest : public testing::Test {
file_util::WriteFile(temp_file1_, kTestFileData1,
arraysize(kTestFileData1) - 1));
base::PlatformFileInfo file_info1;
- file_util::GetFileInfo(temp_file1_, &file_info1);
+ base::GetFileInfo(temp_file1_, &file_info1);
temp_file_modification_time1_ = file_info1.last_modified;
temp_file2_ = temp_dir_.path().AppendASCII("BlobFile2.dat");
@@ -154,7 +154,7 @@ class BlobURLRequestJobTest : public testing::Test {
file_util::WriteFile(temp_file2_, kTestFileData2,
arraysize(kTestFileData2) - 1));
base::PlatformFileInfo file_info2;
- file_util::GetFileInfo(temp_file2_, &file_info2);
+ base::GetFileInfo(temp_file2_, &file_info2);
temp_file_modification_time2_ = file_info2.last_modified;
url_request_job_factory_.SetProtocolHandler("blob",
diff --git a/content/browser/fileapi/dragged_file_util_unittest.cc b/content/browser/fileapi/dragged_file_util_unittest.cc
index 3c34bec3e9..17b29cc6be 100644
--- a/content/browser/fileapi/dragged_file_util_unittest.cc
+++ b/content/browser/fileapi/dragged_file_util_unittest.cc
@@ -326,8 +326,7 @@ TEST_F(DraggedFileUtilTest, UnregisteredPathsTest) {
// Make sure regular GetFileInfo succeeds.
base::PlatformFileInfo info;
- ASSERT_TRUE(file_util::GetFileInfo(
- root_path().Append(test_case.path), &info));
+ ASSERT_TRUE(base::GetFileInfo(root_path().Append(test_case.path), &info));
if (!test_case.is_directory)
ASSERT_EQ(test_case.data_file_size, info.size);
ASSERT_EQ(test_case.is_directory, info.is_directory);
diff --git a/content/browser/fileapi/file_system_context_unittest.cc b/content/browser/fileapi/file_system_context_unittest.cc
index 63365dcef7..43003ad0dc 100644
--- a/content/browser/fileapi/file_system_context_unittest.cc
+++ b/content/browser/fileapi/file_system_context_unittest.cc
@@ -111,6 +111,7 @@ TEST_F(FileSystemContextTest, NullExternalMountPoints) {
ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
"system",
kFileSystemTypeNativeLocal,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/sys/"))));
FileSystemURL cracked_isolated = file_system_context->CrackURL(
@@ -154,6 +155,7 @@ TEST_F(FileSystemContextTest, FileSystemContextKeepsMountPointsAlive) {
ASSERT_TRUE(mount_points->RegisterFileSystem(
"system",
kFileSystemTypeNativeLocal,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/sys/"))));
scoped_refptr<FileSystemContext> file_system_context(
@@ -198,22 +200,26 @@ TEST_F(FileSystemContextTest, CrackFileSystemURL) {
ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
"system",
kFileSystemTypeDrive,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/sys/"))));
ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
"ext",
kFileSystemTypeNativeLocal,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/ext"))));
// Register a system external mount point with the same name/id as the
// registered isolated mount point.
ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
kIsolatedFileSystemID,
kFileSystemTypeRestrictedNativeLocal,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/system/isolated"))));
// Add a mount points with the same name as a system mount point to
// FileSystemContext's external mount points.
ASSERT_TRUE(external_mount_points->RegisterFileSystem(
"ext",
kFileSystemTypeNativeLocal,
+ FileSystemMountOption(),
base::FilePath(DRIVE FPL("/test/local/ext/"))));
const GURL kTestOrigin = GURL("http://chromium.org/");
@@ -351,7 +357,8 @@ TEST_F(FileSystemContextTest, CanServeURLRequest) {
// A request for an external mount point should be served.
const std::string kExternalMountName = "ext_mount";
ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
- kExternalMountName, kFileSystemTypeDrive, base::FilePath()));
+ kExternalMountName, kFileSystemTypeDrive, FileSystemMountOption(),
+ base::FilePath()));
cracked_url = context->CrackURL(
CreateRawFileSystemURL("external", kExternalMountName));
EXPECT_EQ(kFileSystemTypeExternal, cracked_url.mount_type());
diff --git a/content/browser/fileapi/file_system_operation_impl_unittest.cc b/content/browser/fileapi/file_system_operation_impl_unittest.cc
index 23dfedeed7..445657d9a0 100644
--- a/content/browser/fileapi/file_system_operation_impl_unittest.cc
+++ b/content/browser/fileapi/file_system_operation_impl_unittest.cc
@@ -159,7 +159,7 @@ class FileSystemOperationImplTest
int64 GetFileSize(const std::string& path) {
base::PlatformFileInfo info;
- EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(path), &info));
+ EXPECT_TRUE(base::GetFileInfo(PlatformPath(path), &info));
return info.size;
}
@@ -664,7 +664,7 @@ TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirRecursive) {
TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
base::FilePath src_local_disk_file_path;
- file_util::CreateTemporaryFile(&src_local_disk_file_path);
+ base::CreateTemporaryFile(&src_local_disk_file_path);
const char test_data[] = "foo";
int data_size = ARRAYSIZE_UNSAFE(test_data);
file_util::WriteFile(src_local_disk_file_path, test_data, data_size);
@@ -689,15 +689,15 @@ TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
// Compare contents of src and copied file.
char buffer[100];
- EXPECT_EQ(data_size, file_util::ReadFile(PlatformPath("dest/file"),
- buffer, data_size));
+ EXPECT_EQ(data_size, base::ReadFile(PlatformPath("dest/file"),
+ buffer, data_size));
for (int i = 0; i < data_size; ++i)
EXPECT_EQ(test_data[i], buffer[i]);
}
TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileFailureByQuota) {
base::FilePath src_local_disk_file_path;
- file_util::CreateTemporaryFile(&src_local_disk_file_path);
+ base::CreateTemporaryFile(&src_local_disk_file_path);
const char test_data[] = "foo";
file_util::WriteFile(src_local_disk_file_path, test_data,
ARRAYSIZE_UNSAFE(test_data));
@@ -1009,7 +1009,7 @@ TEST_F(FileSystemOperationImplTest, TestTruncate) {
// data.
EXPECT_EQ(length, GetFileSize("file"));
char data[100];
- EXPECT_EQ(length, file_util::ReadFile(platform_path, data, length));
+ EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
for (int i = 0; i < length; ++i) {
if (i < static_cast<int>(sizeof(test_data)))
EXPECT_EQ(test_data[i], data[i]);
@@ -1028,7 +1028,7 @@ TEST_F(FileSystemOperationImplTest, TestTruncate) {
// Check that its length is now 3 and that it contains only bits of test data.
EXPECT_EQ(length, GetFileSize("file"));
- EXPECT_EQ(length, file_util::ReadFile(platform_path, data, length));
+ EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
for (int i = 0; i < length; ++i)
EXPECT_EQ(test_data[i], data[i]);
@@ -1065,7 +1065,7 @@ TEST_F(FileSystemOperationImplTest, TestTouchFile) {
base::FilePath platform_path = PlatformPath("file");
base::PlatformFileInfo info;
- EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info));
+ EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
EXPECT_FALSE(info.is_directory);
EXPECT_EQ(0, info.size);
const base::Time last_modified = info.last_modified;
@@ -1083,7 +1083,7 @@ TEST_F(FileSystemOperationImplTest, TestTouchFile) {
EXPECT_EQ(base::PLATFORM_FILE_OK, status());
EXPECT_TRUE(change_observer()->HasNoChange());
- EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info));
+ EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
// We compare as time_t here to lower our resolution, to avoid false
// negatives caused by conversion to the local filesystem's native
// representation and back.
diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc
index 20607d38cd..b6b89fb50a 100644
--- a/content/browser/fileapi/fileapi_message_filter.cc
+++ b/content/browser/fileapi/fileapi_message_filter.cc
@@ -814,11 +814,22 @@ void FileAPIMessageFilter::DidCreateSnapshot(
bool FileAPIMessageFilter::ValidateFileSystemURL(
int request_id, const fileapi::FileSystemURL& url) {
- if (FileSystemURLIsValid(context_, url))
- return true;
- Send(new FileSystemMsg_DidFail(request_id,
- base::PLATFORM_FILE_ERROR_INVALID_URL));
- return false;
+ if (!FileSystemURLIsValid(context_, url)) {
+ Send(new FileSystemMsg_DidFail(request_id,
+ base::PLATFORM_FILE_ERROR_INVALID_URL));
+ return false;
+ }
+
+ // Deny access to files in PluginPrivate FileSystem from JavaScript.
+ // TODO(nhiroki): Move this filter somewhere else since this is not for
+ // validation.
+ if (url.type() == fileapi::kFileSystemTypePluginPrivate) {
+ Send(new FileSystemMsg_DidFail(request_id,
+ base::PLATFORM_FILE_ERROR_SECURITY));
+ return false;
+ }
+
+ return true;
}
scoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) {
diff --git a/content/browser/fileapi/local_file_util_unittest.cc b/content/browser/fileapi/local_file_util_unittest.cc
index fd28035aaf..40995d6931 100644
--- a/content/browser/fileapi/local_file_util_unittest.cc
+++ b/content/browser/fileapi/local_file_util_unittest.cc
@@ -85,7 +85,7 @@ class LocalFileUtilTest : public testing::Test {
int64 GetSize(const char *file_name) {
base::PlatformFileInfo info;
- file_util::GetFileInfo(LocalPath(file_name), &info);
+ base::GetFileInfo(LocalPath(file_name), &info);
return info.size;
}
@@ -192,7 +192,7 @@ TEST_F(LocalFileUtilTest, TouchFile) {
scoped_ptr<FileSystemOperationContext> context(NewContext());
base::PlatformFileInfo info;
- ASSERT_TRUE(file_util::GetFileInfo(LocalPath(file_name), &info));
+ ASSERT_TRUE(base::GetFileInfo(LocalPath(file_name), &info));
const base::Time new_accessed =
info.last_accessed + base::TimeDelta::FromHours(10);
const base::Time new_modified =
@@ -202,7 +202,7 @@ TEST_F(LocalFileUtilTest, TouchFile) {
file_util()->Touch(context.get(), CreateURL(file_name),
new_accessed, new_modified));
- ASSERT_TRUE(file_util::GetFileInfo(LocalPath(file_name), &info));
+ ASSERT_TRUE(base::GetFileInfo(LocalPath(file_name), &info));
EXPECT_EQ(new_accessed, info.last_accessed);
EXPECT_EQ(new_modified, info.last_modified);
@@ -220,7 +220,7 @@ TEST_F(LocalFileUtilTest, TouchDirectory) {
false /* recursive */));
base::PlatformFileInfo info;
- ASSERT_TRUE(file_util::GetFileInfo(LocalPath(dir_name), &info));
+ ASSERT_TRUE(base::GetFileInfo(LocalPath(dir_name), &info));
const base::Time new_accessed =
info.last_accessed + base::TimeDelta::FromHours(10);
const base::Time new_modified =
@@ -230,7 +230,7 @@ TEST_F(LocalFileUtilTest, TouchDirectory) {
file_util()->Touch(context.get(), CreateURL(dir_name),
new_accessed, new_modified));
- ASSERT_TRUE(file_util::GetFileInfo(LocalPath(dir_name), &info));
+ ASSERT_TRUE(base::GetFileInfo(LocalPath(dir_name), &info));
EXPECT_EQ(new_accessed, info.last_accessed);
EXPECT_EQ(new_modified, info.last_modified);
}
diff --git a/content/browser/fileapi/obfuscated_file_util_unittest.cc b/content/browser/fileapi/obfuscated_file_util_unittest.cc
index 2a9710e6a6..72dd36008d 100644
--- a/content/browser/fileapi/obfuscated_file_util_unittest.cc
+++ b/content/browser/fileapi/obfuscated_file_util_unittest.cc
@@ -44,7 +44,7 @@ bool FileExists(const base::FilePath& path) {
int64 GetSize(const base::FilePath& path) {
int64 size;
- EXPECT_TRUE(file_util::GetFileSize(path, &size));
+ EXPECT_TRUE(base::GetFileSize(path, &size));
return size;
}
@@ -2407,7 +2407,7 @@ TEST_F(ObfuscatedFileUtilTest, MigrationBackFromIsolated) {
// Populate the origin directory with some fake data.
old_directory_db_path = data_dir_path().Append(path);
- ASSERT_TRUE(file_util::CreateDirectory(old_directory_db_path));
+ ASSERT_TRUE(base::CreateDirectory(old_directory_db_path));
EXPECT_EQ(static_cast<int>(kFakeDirectoryData.size()),
file_util::WriteFile(old_directory_db_path.AppendASCII("dummy"),
kFakeDirectoryData.data(),
diff --git a/content/browser/fileapi/transient_file_util_unittest.cc b/content/browser/fileapi/transient_file_util_unittest.cc
index b12a99eecc..2ddb315c55 100644
--- a/content/browser/fileapi/transient_file_util_unittest.cc
+++ b/content/browser/fileapi/transient_file_util_unittest.cc
@@ -40,8 +40,7 @@ class TransientFileUtilTest : public testing::Test {
void CreateAndRegisterTemporaryFile(
FileSystemURL* file_url,
base::FilePath* file_path) {
- EXPECT_TRUE(
- file_util::CreateTemporaryFileInDir(data_dir_.path(), file_path));
+ EXPECT_TRUE(base::CreateTemporaryFileInDir(data_dir_.path(), file_path));
IsolatedContext* isolated_context = IsolatedContext::GetInstance();
std::string name = "tmp";
std::string fsid = isolated_context->RegisterFileSystemForPath(
diff --git a/content/browser/frame_host/OWNERS b/content/browser/frame_host/OWNERS
new file mode 100644
index 0000000000..df8aeac954
--- /dev/null
+++ b/content/browser/frame_host/OWNERS
@@ -0,0 +1 @@
+nasko@chromium.org
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index 303c496ae4..fef82eebab 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -44,19 +44,21 @@ bool FrameTreeNodeForFrameId(int64 frame_id,
} // namespace
FrameTree::FrameTree(Navigator* navigator,
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
RenderFrameHostManager::Delegate* manager_delegate)
- : render_view_delegate_(render_view_delegate),
+ : render_frame_delegate_(render_frame_delegate),
+ render_view_delegate_(render_view_delegate),
render_widget_delegate_(render_widget_delegate),
manager_delegate_(manager_delegate),
root_(new FrameTreeNode(navigator,
+ render_frame_delegate,
render_view_delegate,
render_widget_delegate,
manager_delegate,
FrameTreeNode::kInvalidFrameId,
- std::string(),
- scoped_ptr<RenderFrameHostImpl>())) {
+ std::string())) {
}
FrameTree::~FrameTree() {
@@ -92,22 +94,26 @@ void FrameTree::OnFirstNavigationAfterSwap(int main_frame_id) {
root_->set_frame_id(main_frame_id);
}
-void FrameTree::AddFrame(int render_frame_host_id,
- int64 parent_frame_id,
- int64 frame_id,
- const std::string& frame_name) {
+RenderFrameHostImpl* FrameTree::AddFrame(int render_frame_host_id,
+ int64 parent_frame_id,
+ int64 frame_id,
+ const std::string& frame_name) {
FrameTreeNode* parent = FindByFrameID(parent_frame_id);
// TODO(ajwong): Should the renderer be killed here? Would there be a race on
// shutdown that might make this case possible?
if (!parent)
- return;
+ return NULL;
- parent->AddChild(CreateNode(frame_id, frame_name, render_frame_host_id,
- parent->navigator(),
- parent->render_frame_host()->GetProcess()));
+ scoped_ptr<FrameTreeNode> node(CreateNode(
+ frame_id, frame_name, render_frame_host_id, parent));
+ RenderFrameHostImpl* render_frame = node->render_frame_host();
+ parent->AddChild(node.Pass());
+ return render_frame;
}
-void FrameTree::RemoveFrame(int64 parent_frame_id, int64 frame_id) {
+void FrameTree::RemoveFrame(RenderFrameHostImpl* render_frame_host,
+ int64 parent_frame_id,
+ int64 frame_id) {
// If switches::kSitePerProcess is not specified, then the FrameTree only
// contains a node for the root element. However, even in this case
// frame detachments need to be broadcast outwards.
@@ -119,7 +125,7 @@ void FrameTree::RemoveFrame(int64 parent_frame_id, int64 frame_id) {
FrameTreeNode* child = FindByFrameID(frame_id);
if (!on_frame_removed_.is_null()) {
on_frame_removed_.Run(
- root_->render_frame_host()->render_view_host(), frame_id);
+ render_frame_host->render_view_host(), frame_id);
}
// TODO(ajwong): Should the renderer be killed here? Would there be a race on
@@ -164,18 +170,22 @@ scoped_ptr<FrameTreeNode> FrameTree::CreateNode(
int64 frame_id,
const std::string& frame_name,
int render_frame_host_id,
- Navigator* navigator,
- RenderProcessHost* render_process_host) {
+ FrameTreeNode* parent_node) {
+ scoped_ptr<FrameTreeNode> frame_tree_node(new FrameTreeNode(
+ parent_node->navigator(), render_frame_delegate_, render_view_delegate_,
+ render_widget_delegate_, manager_delegate_, frame_id, frame_name));
+
scoped_ptr<RenderFrameHostImpl> render_frame_host(
RenderFrameHostFactory::Create(
- root_->render_frame_host()->render_view_host(),
+ parent_node->render_frame_host()->render_view_host(),
+ parent_node->render_frame_host()->delegate(),
this,
+ frame_tree_node.get(),
render_frame_host_id,
false));
- return make_scoped_ptr(new FrameTreeNode(navigator,
- render_view_delegate_, render_widget_delegate_, manager_delegate_,
- frame_id, frame_name, render_frame_host.Pass()));
+ frame_tree_node->set_render_frame_host(render_frame_host.release(), true);
+ return frame_tree_node.Pass();
}
} // namespace content
diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h
index 498dc20ffc..3ef2d4c979 100644
--- a/content/browser/frame_host/frame_tree.h
+++ b/content/browser/frame_host/frame_tree.h
@@ -16,6 +16,7 @@ namespace content {
class FrameTreeNode;
class Navigator;
+class RenderFrameHostDelegate;
class RenderProcessHost;
class RenderViewHostDelegate;
class RenderViewHostImpl;
@@ -46,6 +47,7 @@ class CONTENT_EXPORT FrameTree {
// TODO(creis): This set of delegates will change as we move things to
// Navigator.
FrameTree(Navigator* navigator,
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
RenderFrameHostManager::Delegate* manager_delegate);
@@ -72,11 +74,13 @@ class CONTENT_EXPORT FrameTree {
// Frame tree manipulation routines.
// TODO(creis): These should take in RenderFrameHost routing IDs.
- void AddFrame(int render_frame_host_id,
- int64 parent_frame_tree_node_id,
- int64 frame_id,
- const std::string& frame_name);
- void RemoveFrame(int64 parent_frame_id, int64 frame_id);
+ RenderFrameHostImpl* AddFrame(int render_frame_host_id,
+ int64 parent_frame_tree_node_id,
+ int64 frame_id,
+ const std::string& frame_name);
+ void RemoveFrame(RenderFrameHostImpl* render_frame_host,
+ int64 parent_frame_id,
+ int64 frame_id);
void SetFrameUrl(int64 frame_id, const GURL& url);
// Resets the FrameTree and changes RenderFrameHost for the main frame.
@@ -113,11 +117,11 @@ class CONTENT_EXPORT FrameTree {
scoped_ptr<FrameTreeNode> CreateNode(int64 frame_id,
const std::string& frame_name,
int render_frame_host_id,
- Navigator* navigator,
- RenderProcessHost* render_process_host);
+ FrameTreeNode* parent_node);
// These delegates are installed into all the RenderViewHosts and
// RenderFrameHosts that we create.
+ RenderFrameHostDelegate* render_frame_delegate_;
RenderViewHostDelegate* render_view_delegate_;
RenderWidgetHostDelegate* render_widget_delegate_;
RenderFrameHostManager::Delegate* manager_delegate_;
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index 65c20ee05b..37b61b4fad 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -16,21 +16,22 @@ const int64 FrameTreeNode::kInvalidFrameId = -1;
int64 FrameTreeNode::next_frame_tree_node_id_ = 1;
FrameTreeNode::FrameTreeNode(Navigator* navigator,
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
RenderFrameHostManager::Delegate* manager_delegate,
int64 frame_id,
- const std::string& name,
- scoped_ptr<RenderFrameHostImpl> render_frame_host)
+ const std::string& name)
: navigator_(navigator),
- render_manager_(render_view_delegate,
+ render_manager_(render_frame_delegate,
+ render_view_delegate,
render_widget_delegate,
manager_delegate),
frame_tree_node_id_(next_frame_tree_node_id_++),
frame_id_(frame_id),
frame_name_(name),
owns_render_frame_host_(true),
- render_frame_host_(render_frame_host.release()) {
+ render_frame_host_(NULL) {
}
FrameTreeNode::~FrameTreeNode() {
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h
index cc8e9fafa6..9c22b125ba 100644
--- a/content/browser/frame_host/frame_tree_node.h
+++ b/content/browser/frame_host/frame_tree_node.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_frame_host_manager.h"
#include "content/common/content_export.h"
#include "url/gurl.h"
@@ -29,18 +30,27 @@ class CONTENT_EXPORT FrameTreeNode {
static const int64 kInvalidFrameId;
FrameTreeNode(Navigator* navigator,
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
RenderFrameHostManager::Delegate* manager_delegate,
int64 frame_id,
- const std::string& name,
- scoped_ptr<RenderFrameHostImpl> render_frame_host);
+ const std::string& name);
~FrameTreeNode();
void AddChild(scoped_ptr<FrameTreeNode> child);
void RemoveChild(FrameTreeNode* child);
+ // TODO(nasko): This method should be removed once RenderFrameHosts are
+ // created by RenderFrameHostManager.
+ void set_render_frame_host(
+ RenderFrameHostImpl* render_frame_host,
+ bool owns_render_frame_host) {
+ render_frame_host_ = render_frame_host;
+ owns_render_frame_host_ = owns_render_frame_host;
+ }
+
// Transitional API allowing the RenderFrameHost of a FrameTreeNode
// representing the main frame to be provided by someone else. After
// this is called, the FrameTreeNode no longer owns its RenderFrameHost.
diff --git a/content/browser/frame_host/frame_tree_unittest.cc b/content/browser/frame_host/frame_tree_unittest.cc
index 27b8167814..6f1bb33038 100644
--- a/content/browser/frame_host/frame_tree_unittest.cc
+++ b/content/browser/frame_host/frame_tree_unittest.cc
@@ -6,7 +6,7 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
-#include "content/browser/frame_host/navigator.h"
+#include "content/browser/frame_host/navigator_impl.h"
#include "content/browser/frame_host/render_frame_host_factory.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -53,7 +53,7 @@ class FrameTreeTest : public RenderViewHostTestHarness {
// - Swapping back to NULL doesn't crash (easier tear-down for interstitials).
// - Main frame does not own RenderFrameHost.
TEST_F(FrameTreeTest, RootNode) {
- FrameTree frame_tree(new Navigator(NULL, NULL), NULL, NULL, NULL);
+ FrameTree frame_tree(new NavigatorImpl(NULL, NULL), NULL, NULL, NULL, NULL);
// Initial state has empty node.
FrameTreeNode* root = frame_tree.root();
@@ -80,7 +80,7 @@ TEST_F(FrameTreeTest, RootNode) {
// - On creation, frame id is unassigned.
// - After a swap, frame id is unassigned.
TEST_F(FrameTreeTest, FirstNavigationAfterSwap) {
- FrameTree frame_tree(new Navigator(NULL, NULL), NULL, NULL, NULL);
+ FrameTree frame_tree(new NavigatorImpl(NULL, NULL), NULL, NULL, NULL, NULL);
EXPECT_TRUE(frame_tree.IsFirstNavigationAfterSwap());
EXPECT_EQ(FrameTreeNode::kInvalidFrameId,
@@ -99,7 +99,7 @@ TEST_F(FrameTreeTest, FirstNavigationAfterSwap) {
// - Add a series of nodes and verify tree structure.
// - Remove a series of nodes and verify tree structure.
TEST_F(FrameTreeTest, Shape) {
- FrameTree frame_tree(new Navigator(NULL, NULL), NULL, NULL, NULL);
+ FrameTree frame_tree(new NavigatorImpl(NULL, NULL), NULL, NULL, NULL, NULL);
std::string no_children_node("no children node");
std::string deep_subtree("node with deep subtree");
@@ -108,7 +108,9 @@ TEST_F(FrameTreeTest, Shape) {
// main frame swap here.
scoped_ptr<RenderFrameHostImpl> render_frame_host =
RenderFrameHostFactory::Create(static_cast<RenderViewHostImpl*>(rvh()),
+ NULL,
&frame_tree,
+ frame_tree.root(),
process()->GetNextRoutingID(),
false);
frame_tree.SwapMainFrame(render_frame_host.get());
@@ -150,7 +152,7 @@ TEST_F(FrameTreeTest, Shape) {
GetTreeState(&frame_tree));
// Test removing of nodes.
- frame_tree.RemoveFrame(555, 655);
+ frame_tree.RemoveFrame(NULL, 555, 655);
ASSERT_EQ("5: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: [264: [], 265: [], 266: [], "
@@ -158,7 +160,7 @@ TEST_F(FrameTreeTest, Shape) {
"[365: [455: [555: []]]], 268: []]]",
GetTreeState(&frame_tree));
- frame_tree.RemoveFrame(16, 265);
+ frame_tree.RemoveFrame(NULL, 16, 265);
ASSERT_EQ("5: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: [264: [], 266: [], "
@@ -166,7 +168,7 @@ TEST_F(FrameTreeTest, Shape) {
"[365: [455: [555: []]]], 268: []]]",
GetTreeState(&frame_tree));
- frame_tree.RemoveFrame(5, 15);
+ frame_tree.RemoveFrame(NULL, 5, 15);
ASSERT_EQ("5: [14: [244: [], 245: []], "
"16: [264: [], 266: [], "
"267 'node with deep subtree': "
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc
index 8b249e924e..7af8d029f7 100644
--- a/content/browser/frame_host/interstitial_page_impl.cc
+++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -14,9 +14,9 @@
#include "base/threading/thread.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
+#include "content/browser/frame_host/interstitial_page_navigator_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
-#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
@@ -161,7 +161,8 @@ InterstitialPageImpl::InterstitialPageImpl(
// While we get the code to a point to do this, pass NULL for it.
// TODO(creis): We will also need to pass delegates for the RVHM as we
// start to use it.
- frame_tree_(new Navigator(NULL, this), NULL, NULL, NULL),
+ frame_tree_(new InterstitialPageNavigatorImpl(this, controller_),
+ NULL, NULL, NULL, NULL),
original_child_id_(web_contents->GetRenderProcessHost()->GetID()),
original_rvh_id_(web_contents->GetRenderViewHost()->GetRoutingID()),
should_revert_web_contents_title_(false),
@@ -431,7 +432,7 @@ void InterstitialPageImpl::DidNavigate(
void InterstitialPageImpl::UpdateTitle(
RenderViewHost* render_view_host,
int32 page_id,
- const string16& title,
+ const base::string16& title,
base::i18n::TextDirection title_direction) {
if (!enabled())
return;
@@ -526,6 +527,7 @@ RenderViewHost* InterstitialPageImpl::CreateRenderViewHost() {
return RenderViewHostFactory::Create(site_instance.get(),
this,
this,
+ this,
MSG_ROUTING_NONE,
MSG_ROUTING_NONE,
false,
@@ -545,7 +547,7 @@ WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
int32 max_page_id = web_contents()->
GetMaxPageIDForSiteInstance(render_view_host_->GetSiteInstance());
- render_view_host_->CreateRenderView(string16(),
+ render_view_host_->CreateRenderView(base::string16(),
MSG_ROUTING_NONE,
max_page_id);
controller_->delegate()->RenderViewForInterstitialPageCreated(
@@ -697,6 +699,7 @@ gfx::Rect InterstitialPageImpl::GetRootWindowResizerRect() const {
}
void InterstitialPageImpl::CreateNewWindow(
+ int render_process_id,
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
@@ -704,12 +707,14 @@ void InterstitialPageImpl::CreateNewWindow(
NOTREACHED() << "InterstitialPage does not support showing popups yet.";
}
-void InterstitialPageImpl::CreateNewWidget(int route_id,
+void InterstitialPageImpl::CreateNewWidget(int render_process_id,
+ int route_id,
blink::WebPopupType popup_type) {
NOTREACHED() << "InterstitialPage does not support showing drop-downs yet.";
}
-void InterstitialPageImpl::CreateNewFullscreenWidget(int route_id) {
+void InterstitialPageImpl::CreateNewFullscreenWidget(int render_process_id,
+ int route_id) {
NOTREACHED()
<< "InterstitialPage does not support showing full screen popups.";
}
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h
index 47a127e823..fddeacd10f 100644
--- a/content/browser/frame_host/interstitial_page_impl.h
+++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/public/browser/interstitial_page.h"
@@ -22,7 +23,6 @@
namespace content {
class NavigationEntry;
class NavigationControllerImpl;
-class Navigator;
class RenderViewHostImpl;
class RenderWidgetHostView;
class WebContentsView;
@@ -38,6 +38,7 @@ class CONTENT_EXPORT InterstitialPageImpl
: public NON_EXPORTED_BASE(InterstitialPage),
public NotificationObserver,
public WebContentsObserver,
+ public NON_EXPORTED_BASE(RenderFrameHostDelegate),
public RenderViewHostDelegate,
public RenderWidgetHostDelegate,
public NON_EXPORTED_BASE(NavigatorDelegate) {
@@ -101,6 +102,8 @@ class CONTENT_EXPORT InterstitialPageImpl
virtual void NavigationEntryCommitted(
const LoadCommittedDetails& load_details) OVERRIDE;
+ // RenderFrameHostDelegate implementation:
+
// RenderViewHostDelegate implementation:
virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE;
virtual const GURL& GetURL() const OVERRIDE;
@@ -112,20 +115,23 @@ class CONTENT_EXPORT InterstitialPageImpl
const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
virtual void UpdateTitle(RenderViewHost* render_view_host,
int32 page_id,
- const string16& title,
+ const base::string16& title,
base::i18n::TextDirection title_direction) OVERRIDE;
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE;
virtual WebPreferences GetWebkitPrefs() OVERRIDE;
virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE;
virtual void CreateNewWindow(
+ int render_process_id,
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) OVERRIDE;
- virtual void CreateNewWidget(int route_id,
+ virtual void CreateNewWidget(int render_process_id,
+ int route_id,
blink::WebPopupType popup_type) OVERRIDE;
- virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE;
+ virtual void CreateNewFullscreenWidget(int render_process_id,
+ int route_id) OVERRIDE;
virtual void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
@@ -246,7 +252,7 @@ class CONTENT_EXPORT InterstitialPageImpl
// The original title of the contents that should be reverted to when the
// interstitial is hidden.
- string16 original_web_contents_title_;
+ base::string16 original_web_contents_title_;
// Our RenderViewHostViewDelegate, necessary for accelerators to work.
scoped_ptr<InterstitialPageRVHDelegateView> rvh_delegate_view_;
diff --git a/content/browser/frame_host/interstitial_page_navigator_impl.cc b/content/browser/frame_host/interstitial_page_navigator_impl.cc
new file mode 100644
index 0000000000..830e1bfde1
--- /dev/null
+++ b/content/browser/frame_host/interstitial_page_navigator_impl.cc
@@ -0,0 +1,17 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/interstitial_page_navigator_impl.h"
+
+#include "content/browser/frame_host/interstitial_page_impl.h"
+#include "content/browser/frame_host/navigator_delegate.h"
+
+namespace content {
+
+InterstitialPageNavigatorImpl::InterstitialPageNavigatorImpl(
+ InterstitialPageImpl* interstitial,
+ NavigationControllerImpl* navigation_controller) {
+}
+
+} // namespace content
diff --git a/content/browser/frame_host/interstitial_page_navigator_impl.h b/content/browser/frame_host/interstitial_page_navigator_impl.h
new file mode 100644
index 0000000000..1b55fd21a3
--- /dev/null
+++ b/content/browser/frame_host/interstitial_page_navigator_impl.h
@@ -0,0 +1,33 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_NAVIGATOR_IMPL_H_
+#define CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_NAVIGATOR_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "content/browser/frame_host/navigator.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class NavigationControllerImpl;
+class InterstitialPageImpl;
+
+// Navigator implementation specific to InterstialPageImpl. It allows only one
+// navigation to commit, since interstitial pages are not allowed to navigate.
+class CONTENT_EXPORT InterstitialPageNavigatorImpl : public Navigator {
+ public:
+ InterstitialPageNavigatorImpl(
+ InterstitialPageImpl* interstitial,
+ NavigationControllerImpl* navigation_controller);
+
+ private:
+ virtual ~InterstitialPageNavigatorImpl() {}
+
+ DISALLOW_COPY_AND_ASSIGN(InterstitialPageNavigatorImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_INTERSTITIAL_PAGE_NAVIGATOR_IMPL_H_
diff --git a/content/browser/frame_host/navigation_controller_android.cc b/content/browser/frame_host/navigation_controller_android.cc
new file mode 100644
index 0000000000..536e17dd3e
--- /dev/null
+++ b/content/browser/frame_host/navigation_controller_android.cc
@@ -0,0 +1,73 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/navigation_controller_android.h"
+
+#include "base/android/jni_android.h"
+#include "content/public/browser/navigation_controller.h"
+#include "jni/NavigationControllerImpl_jni.h"
+
+using base::android::AttachCurrentThread;
+
+namespace content {
+
+// static
+bool NavigationControllerAndroid::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+NavigationControllerAndroid::NavigationControllerAndroid(
+ NavigationController* navigation_controller)
+ : navigation_controller_(navigation_controller) {
+ JNIEnv* env = AttachCurrentThread();
+ obj_.Reset(env,
+ Java_NavigationControllerImpl_create(
+ env, reinterpret_cast<intptr_t>(this)).obj());
+}
+
+NavigationControllerAndroid::~NavigationControllerAndroid() {
+ Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_.obj());
+}
+
+base::android::ScopedJavaLocalRef<jobject>
+NavigationControllerAndroid::GetJavaObject() {
+ return base::android::ScopedJavaLocalRef<jobject>(obj_);
+}
+
+jboolean NavigationControllerAndroid::CanGoBack(JNIEnv* env, jobject obj) {
+ return navigation_controller_->CanGoBack();
+}
+
+jboolean NavigationControllerAndroid::CanGoForward(JNIEnv* env,
+ jobject obj) {
+ return navigation_controller_->CanGoForward();
+}
+
+jboolean NavigationControllerAndroid::CanGoToOffset(JNIEnv* env,
+ jobject obj,
+ jint offset) {
+ return navigation_controller_->CanGoToOffset(offset);
+}
+
+void NavigationControllerAndroid::GoBack(JNIEnv* env, jobject obj) {
+ navigation_controller_->GoBack();
+}
+
+void NavigationControllerAndroid::GoForward(JNIEnv* env, jobject obj) {
+ navigation_controller_->GoForward();
+}
+
+void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
+ jobject obj,
+ jint offset) {
+ navigation_controller_->GoToOffset(offset);
+}
+
+void NavigationControllerAndroid::GoToNavigationIndex(JNIEnv* env,
+ jobject obj,
+ jint index) {
+ navigation_controller_->GoToIndex(index);
+}
+
+} // namespace content
diff --git a/content/browser/frame_host/navigation_controller_android.h b/content/browser/frame_host/navigation_controller_android.h
new file mode 100644
index 0000000000..e0c96a63a0
--- /dev/null
+++ b/content/browser/frame_host/navigation_controller_android.h
@@ -0,0 +1,53 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_ANDROID_H_
+#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class NavigationController;
+
+// Android wrapper around NavigationController that provides safer passage
+// from java and back to native and provides java with a means of communicating
+// with its native counterpart.
+class CONTENT_EXPORT NavigationControllerAndroid {
+ public:
+ static bool Register(JNIEnv* env);
+
+ explicit NavigationControllerAndroid(
+ NavigationController* navigation_controller);
+ ~NavigationControllerAndroid();
+
+ NavigationController* navigation_controller() const {
+ return navigation_controller_;
+ }
+
+ base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
+ jboolean CanGoBack(JNIEnv* env, jobject obj);
+ jboolean CanGoForward(JNIEnv* env, jobject obj);
+ jboolean CanGoToOffset(JNIEnv* env, jobject obj, jint offset);
+ void GoBack(JNIEnv* env, jobject obj);
+ void GoForward(JNIEnv* env, jobject obj);
+ void GoToOffset(JNIEnv* env, jobject obj, jint offset);
+ void GoToNavigationIndex(JNIEnv* env, jobject obj, jint index);
+
+ private:
+ NavigationController* navigation_controller_;
+ base::android::ScopedJavaGlobalRef<jobject> obj_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationControllerAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_NAVIGATION_CONTROLLER_ANDROID_H_
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 0c6f803cb8..a49a9323fa 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -163,7 +163,7 @@ NavigationEntry* NavigationController::CreateNavigationEntry(
-1,
loaded_url,
referrer,
- string16(),
+ base::string16(),
transition,
is_renderer_initiated);
entry->SetVirtualURL(url);
@@ -354,7 +354,7 @@ void NavigationControllerImpl::ReloadInternal(bool check_for_repost,
// meanwhile, so we need to revert to the default title upon reload and
// invalidate the previously cached title (SetTitle will do both).
// See Chromium issue 96041.
- pending_entry_->SetTitle(string16());
+ pending_entry_->SetTitle(base::string16());
pending_entry_->SetTransitionType(PAGE_TRANSITION_RELOAD);
}
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 1f31e11b3d..2f0cac26e3 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -14,7 +14,7 @@
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
+#include "content/browser/frame_host/navigator.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
@@ -29,6 +29,7 @@
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_notification_tracker.h"
#include "content/public/test/test_utils.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "net/base/net_util.h"
#include "skia/ext/platform_canvas.h"
@@ -921,7 +922,7 @@ TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) {
params.frame_id = 1;
params.is_main_frame = true;
params.error_code = net::ERR_ABORTED;
- params.error_description = string16();
+ params.error_description = base::string16();
params.url = kNewURL;
params.showing_repost_interstitial = false;
test_rvh()->OnMessageReceived(
@@ -999,7 +1000,7 @@ TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
params.frame_id = 1;
params.is_main_frame = true;
params.error_code = net::ERR_ABORTED;
- params.error_description = string16();
+ params.error_description = base::string16();
params.url = kRedirectURL;
params.showing_repost_interstitial = false;
test_rvh()->OnMessageReceived(
@@ -2342,7 +2343,7 @@ TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) {
fail_load_params.frame_id = 1;
fail_load_params.is_main_frame = true;
fail_load_params.error_code = net::ERR_ABORTED;
- fail_load_params.error_description = string16();
+ fail_load_params.error_description = base::string16();
fail_load_params.url = url;
fail_load_params.showing_repost_interstitial = false;
rvh->OnMessageReceived(
@@ -2648,6 +2649,8 @@ TEST_F(NavigationControllerTest, ReloadTransient) {
// See http://crbug.com/266922.
TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
NavigationControllerImpl& controller = controller_impl();
+ Navigator* navigator =
+ contents()->GetFrameTree()->root()->navigator();
const GURL url1("nonexistent:12121");
const GURL url1_fixed("http://nonexistent:12121/");
@@ -2655,8 +2658,7 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
// We create pending entries for renderer-initiated navigations so that we
// can show them in new tabs when it is safe.
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
// Simulate what happens if a BrowserURLHandler rewrites the URL, causing
// the virtual URL to differ from the URL.
@@ -2670,8 +2672,7 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
is_renderer_initiated());
// If the user clicks another link, we should replace the pending entry.
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, url2);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2);
EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
@@ -2681,24 +2682,24 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
// We should not replace the pending entry for an error URL.
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, GURL(kUnreachableWebDataURL));
+ navigator->DidStartProvisionalLoad(
+ main_test_rfh(), 1, -1, true, GURL(kUnreachableWebDataURL));
EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
// We should remember if the pending entry will replace the current one.
// http://crbug.com/308444.
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, url1);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
set_should_replace_entry(true);
- contents()->DidStartProvisionalLoadForFrame(
- test_rvh(), 1, -1, true, url2);
+ navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2);
EXPECT_TRUE(
NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
should_replace_entry());
+ // TODO(nasko): Until OnNavigate is moved to RenderFrameHost, we need
+ // to go through the RenderViewHost. The TestRenderViewHost routes navigations
+ // to the main frame.
test_rvh()->SendNavigate(0, url2);
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
}
@@ -2897,7 +2898,7 @@ TEST_F(NavigationControllerTest, CloneAndGoBack) {
NavigationControllerImpl& controller = controller_impl();
const GURL url1("http://foo1");
const GURL url2("http://foo2");
- const string16 title(ASCIIToUTF16("Title"));
+ const base::string16 title(ASCIIToUTF16("Title"));
NavigateAndCommit(url1);
controller.GetVisibleEntry()->SetTitle(title);
@@ -2922,7 +2923,7 @@ TEST_F(NavigationControllerTest, CloneAndReload) {
NavigationControllerImpl& controller = controller_impl();
const GURL url1("http://foo1");
const GURL url2("http://foo2");
- const string16 title(ASCIIToUTF16("Title"));
+ const base::string16 title(ASCIIToUTF16("Title"));
NavigateAndCommit(url1);
controller.GetVisibleEntry()->SetTitle(title);
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index a9b37cc5db..d5d6fc2c98 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -60,7 +60,7 @@ NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance,
int page_id,
const GURL& url,
const Referrer& referrer,
- const string16& title,
+ const base::string16& title,
PageTransition transition_type,
bool is_renderer_initiated)
: unique_id_(GetUniqueIDInConstructor()),
@@ -130,12 +130,12 @@ const GURL& NavigationEntryImpl::GetVirtualURL() const {
return virtual_url_.is_empty() ? url_ : virtual_url_;
}
-void NavigationEntryImpl::SetTitle(const string16& title) {
+void NavigationEntryImpl::SetTitle(const base::string16& title) {
title_ = title;
cached_display_title_.clear();
}
-const string16& NavigationEntryImpl::GetTitle() const {
+const base::string16& NavigationEntryImpl::GetTitle() const {
return title_;
}
@@ -166,7 +166,7 @@ void NavigationEntryImpl::SetBindings(int bindings) {
bindings_ = bindings;
}
-const string16& NavigationEntryImpl::GetTitleForDisplay(
+const base::string16& NavigationEntryImpl::GetTitleForDisplay(
const std::string& languages) const {
// Most pages have real titles. Don't even bother caching anything if this is
// the case.
@@ -179,7 +179,7 @@ const string16& NavigationEntryImpl::GetTitleForDisplay(
return cached_display_title_;
// Use the virtual URL first if any, and fall back on using the real URL.
- string16 title;
+ base::string16 title;
if (!virtual_url_.is_empty()) {
title = net::FormatUrl(virtual_url_, languages);
} else if (!url_.is_empty()) {
@@ -188,8 +188,8 @@ const string16& NavigationEntryImpl::GetTitleForDisplay(
// For file:// URLs use the filename as the title, not the full path.
if (url_.SchemeIsFile()) {
- string16::size_type slashpos = title.rfind('/');
- if (slashpos != string16::npos)
+ base::string16::size_type slashpos = title.rfind('/');
+ if (slashpos != base::string16::npos)
title = title.substr(slashpos + 1);
}
@@ -306,13 +306,14 @@ const std::string& NavigationEntryImpl::GetFrameToNavigate() const {
}
void NavigationEntryImpl::SetExtraData(const std::string& key,
- const string16& data) {
+ const base::string16& data) {
extra_data_[key] = data;
}
bool NavigationEntryImpl::GetExtraData(const std::string& key,
- string16* data) const {
- std::map<std::string, string16>::const_iterator iter = extra_data_.find(key);
+ base::string16* data) const {
+ std::map<std::string, base::string16>::const_iterator iter =
+ extra_data_.find(key);
if (iter == extra_data_.end())
return false;
*data = iter->second;
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h
index c7f4f5fc7c..8a518888ce 100644
--- a/content/browser/frame_host/navigation_entry_impl.h
+++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -29,7 +29,7 @@ class CONTENT_EXPORT NavigationEntryImpl
int page_id,
const GURL& url,
const Referrer& referrer,
- const string16& title,
+ const base::string16& title,
PageTransition transition_type,
bool is_renderer_initiated);
virtual ~NavigationEntryImpl();
@@ -45,13 +45,13 @@ class CONTENT_EXPORT NavigationEntryImpl
virtual const Referrer& GetReferrer() const OVERRIDE;
virtual void SetVirtualURL(const GURL& url) OVERRIDE;
virtual const GURL& GetVirtualURL() const OVERRIDE;
- virtual void SetTitle(const string16& title) OVERRIDE;
- virtual const string16& GetTitle() const OVERRIDE;
+ virtual void SetTitle(const base::string16& title) OVERRIDE;
+ virtual const base::string16& GetTitle() const OVERRIDE;
virtual void SetPageState(const PageState& state) OVERRIDE;
virtual const PageState& GetPageState() const OVERRIDE;
virtual void SetPageID(int page_id) OVERRIDE;
virtual int32 GetPageID() const OVERRIDE;
- virtual const string16& GetTitleForDisplay(
+ virtual const base::string16& GetTitleForDisplay(
const std::string& languages) const OVERRIDE;
virtual bool IsViewSourceMode() const OVERRIDE;
virtual void SetTransitionType(PageTransition transition_type) OVERRIDE;
@@ -80,9 +80,9 @@ class CONTENT_EXPORT NavigationEntryImpl
virtual void SetFrameToNavigate(const std::string& frame_name) OVERRIDE;
virtual const std::string& GetFrameToNavigate() const OVERRIDE;
virtual void SetExtraData(const std::string& key,
- const string16& data) OVERRIDE;
+ const base::string16& data) OVERRIDE;
virtual bool GetExtraData(const std::string& key,
- string16* data) const OVERRIDE;
+ base::string16* data) const OVERRIDE;
virtual void ClearExtraData(const std::string& key) OVERRIDE;
virtual void SetHttpStatusCode(int http_status_code) OVERRIDE;
virtual int GetHttpStatusCode() const OVERRIDE;
@@ -243,7 +243,7 @@ class CONTENT_EXPORT NavigationEntryImpl
Referrer referrer_;
GURL virtual_url_;
bool update_virtual_url_with_url_;
- string16 title_;
+ base::string16 title_;
FaviconStatus favicon_;
PageState page_state_;
int32 page_id_;
@@ -290,7 +290,7 @@ class CONTENT_EXPORT NavigationEntryImpl
// us from having to do URL formatting on the URL every time the title is
// displayed. When the URL, virtual URL, or title is set, this should be
// cleared to force a refresh.
- mutable string16 cached_display_title_;
+ mutable base::string16 cached_display_title_;
// In case a navigation is transferred to a new RVH but the request has
// been generated in the renderer already, this identifies the old request so
@@ -342,7 +342,7 @@ class CONTENT_EXPORT NavigationEntryImpl
// Used to store extra data to support browser features. This member is not
// persisted, unless specific data is taken out/put back in at save/restore
// time (see TabNavigation for an example of this).
- std::map<std::string, string16> extra_data_;
+ std::map<std::string, base::string16> extra_data_;
// Copy and assignment is explicitly allowed for this class.
};
diff --git a/content/browser/frame_host/navigation_entry_impl_unittest.cc b/content/browser/frame_host/navigation_entry_impl_unittest.cc
index cb742e497b..488106fefe 100644
--- a/content/browser/frame_host/navigation_entry_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_entry_impl_unittest.cc
@@ -136,7 +136,7 @@ TEST_F(NavigationEntryTest, NavigationEntryAccessors) {
EXPECT_EQ(GURL("from2"), entry2_->GetReferrer().url);
// Title
- EXPECT_EQ(string16(), entry1_->GetTitle());
+ EXPECT_EQ(base::string16(), entry1_->GetTitle());
EXPECT_EQ(ASCIIToUTF16("title"), entry2_->GetTitle());
entry2_->SetTitle(ASCIIToUTF16("title2"));
EXPECT_EQ(ASCIIToUTF16("title2"), entry2_->GetTitle());
@@ -219,8 +219,8 @@ TEST_F(NavigationEntryTest, NavigationEntryTimestamps) {
// Test extra data stored in the navigation entry.
TEST_F(NavigationEntryTest, NavigationEntryExtraData) {
- string16 test_data = ASCIIToUTF16("my search terms");
- string16 output;
+ base::string16 test_data = ASCIIToUTF16("my search terms");
+ base::string16 output;
entry1_->SetExtraData("search_terms", test_data);
EXPECT_FALSE(entry1_->GetExtraData("non_existent_key", &output));
@@ -233,7 +233,7 @@ TEST_F(NavigationEntryTest, NavigationEntryExtraData) {
EXPECT_FALSE(entry1_->GetExtraData("search_terms", &output));
EXPECT_EQ(test_data, output);
// Using an empty string shows that the data is not present in the map.
- string16 output2;
+ base::string16 output2;
EXPECT_FALSE(entry1_->GetExtraData("search_terms", &output2));
EXPECT_EQ(ASCIIToUTF16(""), output2);
}
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc
deleted file mode 100644
index 4ca26b68ef..0000000000
--- a/content/browser/frame_host/navigator.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/frame_host/navigator.h"
-
-#include "content/browser/frame_host/navigator_delegate.h"
-
-namespace content {
-
-Navigator::Navigator(
- NavigationControllerImpl* nav_controller,
- NavigatorDelegate* delegate)
- : controller_(nav_controller),
- delegate_(delegate) {
-}
-
-} // namespace content
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index c20c9dd9c1..d6658e4cd9 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -8,44 +8,33 @@
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
+class GURL;
+
namespace content {
class NavigationControllerImpl;
class NavigatorDelegate;
+class RenderFrameHostImpl;
-// This class is responsible for performing navigations in a node of the
-// FrameTree. Its lifetime is bound to all FrameTreeNode objects that are
-// using it and will be released once all nodes that use it are freed.
-// The Navigator is bound to a single frame tree and cannot be used by multiple
-// instances of FrameTree.
+// Implementations of this interface are responsible for performing navigations
+// in a node of the FrameTree. Its lifetime is bound to all FrameTreeNode
+// objects that are using it and will be released once all nodes that use it are
+// freed. The Navigator is bound to a single frame tree and cannot be used by
+// multiple instances of FrameTree.
// TODO(nasko): Move all navigation methods, such as didStartProvisionalLoad
-// from WebContentsImpl to this class.
+// from WebContentsImpl to this interface.
class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
public:
- Navigator(NavigationControllerImpl* nav_controller,
- NavigatorDelegate* delegate);
-
- NavigationControllerImpl* controller() {
- return controller_;
- }
-
- NavigatorDelegate* delegate() {
- return delegate_;
- }
-
- private:
+ // The RenderFrameHostImpl started a provisional load.
+ virtual void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host,
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool main_frame,
+ const GURL& url) {};
+
+ protected:
friend class base::RefCounted<Navigator>;
virtual ~Navigator() {}
-
- // The NavigationController that will keep track of session history for all
- // RenderFrameHost objects using this Navigator.
- // TODO(nasko): Move ownership of the NavigationController from
- // WebContentsImpl to this class.
- NavigationControllerImpl* controller_;
-
- // Used to notify the object embedding this Navigator about navigation
- // events. Can be NULL in tests.
- NavigatorDelegate* delegate_;
};
} // namespace content
diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h
index c906b6b111..62b5b48b0b 100644
--- a/content/browser/frame_host/navigator_delegate.h
+++ b/content/browser/frame_host/navigator_delegate.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_DELEGATE_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_DELEGATE_H_
+#include "content/public/browser/invalidate_type.h"
+
namespace content {
class RenderFrameHost;
@@ -12,10 +14,22 @@ class RenderFrameHost;
// A delegate API used by Navigator to notify its embedder of navigation
// related events.
class NavigatorDelegate {
- // TODO(nasko): This class will be used to dispatch notifications to
- // WebContentsImpl, such as DidStartProvisionalLoad and
- // NotifyNavigationStateChanged. Longer term, most of the
- // NavigationControllerDelegate methods will likely move here.
+ public:
+ // The RenderFrameHost started a provisional load for the frame
+ // represented by |render_frame_host|.
+ virtual void DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool is_main_frame,
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc) {}
+
+ // Notification to the Navigator embedder that navigation state has
+ // changed. This method corresponds to
+ // WebContents::NotifyNavigationStateChanged.
+ virtual void NotifyChangedNavigationState(InvalidateTypes changed_flags) {}
};
} // namspace content
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
new file mode 100644
index 0000000000..6cc9dad148
--- /dev/null
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -0,0 +1,85 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/navigator_impl.h"
+
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigation_controller_impl.h"
+#include "content/browser/frame_host/navigation_entry_impl.h"
+#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/site_instance_impl.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/invalidate_type.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/common/url_constants.h"
+
+namespace content {
+
+NavigatorImpl::NavigatorImpl(
+ NavigationControllerImpl* navigation_controller,
+ NavigatorDelegate* delegate)
+ : controller_(navigation_controller),
+ delegate_(delegate) {
+}
+
+void NavigatorImpl::DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool is_main_frame,
+ const GURL& url) {
+ bool is_error_page = (url.spec() == kUnreachableWebDataURL);
+ bool is_iframe_srcdoc = (url.spec() == kAboutSrcDocURL);
+ GURL validated_url(url);
+ RenderProcessHost* render_process_host = render_frame_host->GetProcess();
+ RenderViewHost::FilterURL(render_process_host, false, &validated_url);
+
+ if (is_main_frame) {
+ // If there is no browser-initiated pending entry for this navigation and it
+ // is not for the error URL, create a pending entry using the current
+ // SiteInstance, and ensure the address bar updates accordingly. We don't
+ // know the referrer or extra headers at this point, but the referrer will
+ // be set properly upon commit.
+ NavigationEntryImpl* pending_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ controller_->GetPendingEntry());
+ bool has_browser_initiated_pending_entry = pending_entry &&
+ !pending_entry->is_renderer_initiated();
+ if (!has_browser_initiated_pending_entry && !is_error_page) {
+ NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ controller_->CreateNavigationEntry(validated_url,
+ content::Referrer(),
+ content::PAGE_TRANSITION_LINK,
+ true /* is_renderer_initiated */,
+ std::string(),
+ controller_->GetBrowserContext()));
+ entry->set_site_instance(
+ static_cast<SiteInstanceImpl*>(
+ render_frame_host->render_view_host()->GetSiteInstance()));
+ // TODO(creis): If there's a pending entry already, find a safe way to
+ // update it instead of replacing it and copying over things like this.
+ if (pending_entry) {
+ entry->set_transferred_global_request_id(
+ pending_entry->transferred_global_request_id());
+ entry->set_should_replace_entry(pending_entry->should_replace_entry());
+ entry->set_redirect_chain(pending_entry->redirect_chain());
+ }
+ controller_->SetPendingEntry(entry);
+ if (delegate_)
+ delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL);
+ }
+ }
+
+ if (delegate_) {
+ // Notify the observer about the start of the provisional load.
+ delegate_->DidStartProvisionalLoad(
+ render_frame_host, frame_id, parent_frame_id, is_main_frame,
+ validated_url, is_error_page, is_iframe_srcdoc);
+ }
+}
+
+} // namespace content
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h
new file mode 100644
index 0000000000..b66b87de03
--- /dev/null
+++ b/content/browser/frame_host/navigator_impl.h
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_IMPL_H_
+#define CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "content/browser/frame_host/navigator.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class NavigationControllerImpl;
+class NavigatorDelegate;
+
+// This class is an implementation of Navigator, responsible for managing
+// navigations in regular browser tabs.
+class CONTENT_EXPORT NavigatorImpl : public Navigator {
+ public:
+ NavigatorImpl(NavigationControllerImpl* navigation_controller,
+ NavigatorDelegate* delegate);
+
+ // Navigator implementation.
+ virtual void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host,
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool main_frame,
+ const GURL& url) OVERRIDE;
+
+ private:
+ virtual ~NavigatorImpl() {}
+
+ // The NavigationController that will keep track of session history for all
+ // RenderFrameHost objects using this NavigatorImpl.
+ // TODO(nasko): Move ownership of the NavigationController from
+ // WebContentsImpl to this class.
+ NavigationControllerImpl* controller_;
+
+ // Used to notify the object embedding this Navigator about navigation
+ // events. Can be NULL in tests.
+ NavigatorDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigatorImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_IMPL_H_
diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
new file mode 100644
index 0000000000..14ed0ad4cb
--- /dev/null
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -0,0 +1,15 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/render_frame_host_delegate.h"
+
+namespace content {
+
+bool RenderFrameHostDelegate::OnMessageReceived(
+ RenderFrameHost* render_view_host,
+ const IPC::Message& message) {
+ return false;
+}
+
+} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
new file mode 100644
index 0000000000..1de47dff37
--- /dev/null
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -0,0 +1,37 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_DELEGATE_H_
+#define CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_DELEGATE_H_
+
+#include "content/common/content_export.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+class RenderFrameHost;
+
+// An interface implemented by an object interested in knowing about the state
+// of the RenderFrameHost.
+class CONTENT_EXPORT RenderFrameHostDelegate {
+ public:
+ // This is used to give the delegate a chance to filter IPC messages.
+ virtual bool OnMessageReceived(RenderFrameHost* render_frame_host,
+ const IPC::Message& message);
+
+ // Informs the delegate whenever a RenderFrameHost is created.
+ virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) {}
+
+ // Informs the delegate whenever a RenderFrameHost is deleted.
+ virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) {}
+
+ protected:
+ virtual ~RenderFrameHostDelegate() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_RENDER_FRAME_HOST_DELEGATE_H_
diff --git a/content/browser/frame_host/render_frame_host_factory.cc b/content/browser/frame_host/render_frame_host_factory.cc
index 8e9215c33a..4262c1c7eb 100644
--- a/content/browser/frame_host/render_frame_host_factory.cc
+++ b/content/browser/frame_host/render_frame_host_factory.cc
@@ -5,6 +5,7 @@
#include "content/browser/frame_host/render_frame_host_factory.h"
#include "base/logging.h"
+#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
namespace content {
@@ -15,17 +16,22 @@ RenderFrameHostFactory* RenderFrameHostFactory::factory_ = NULL;
// static
scoped_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
RenderViewHostImpl* render_view_host,
+ RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
+ FrameTreeNode* frame_tree_node,
int routing_id,
bool is_swapped_out) {
if (factory_) {
return factory_->CreateRenderFrameHost(render_view_host,
+ delegate,
frame_tree,
+ frame_tree_node,
routing_id,
is_swapped_out).Pass();
}
return make_scoped_ptr(new RenderFrameHostImpl(
- render_view_host, frame_tree, routing_id, is_swapped_out));
+ render_view_host, delegate, frame_tree, frame_tree_node, routing_id,
+ is_swapped_out));
}
// static
diff --git a/content/browser/frame_host/render_frame_host_factory.h b/content/browser/frame_host/render_frame_host_factory.h
index 4b6e2b6b54..ce8433d088 100644
--- a/content/browser/frame_host/render_frame_host_factory.h
+++ b/content/browser/frame_host/render_frame_host_factory.h
@@ -12,6 +12,8 @@
namespace content {
class FrameTree;
+class FrameTreeNode;
+class RenderFrameHostDelegate;
class RenderFrameHostImpl;
class RenderViewHostImpl;
@@ -24,7 +26,9 @@ class CONTENT_EXPORT RenderFrameHostFactory {
// or a regular RenderFrameHostImpl if no factory is registered.
static scoped_ptr<RenderFrameHostImpl> Create(
RenderViewHostImpl* render_view_host,
+ RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
+ FrameTreeNode* frame_tree_node,
int routing_id,
bool is_swapped_out);
@@ -39,7 +43,9 @@ class CONTENT_EXPORT RenderFrameHostFactory {
// function to create an alternate kind of RenderFrameHostImpl for testing.
virtual scoped_ptr<RenderFrameHostImpl> CreateRenderFrameHost(
RenderViewHostImpl* render_view_host,
+ RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
+ FrameTreeNode* frame_tree_node,
int routing_id,
bool is_swapped_out) = 0;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c1fbc30751..658e834230 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -7,10 +7,14 @@
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/frame_host/navigator.h"
+#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/user_metrics.h"
#include "url/gurl.h"
namespace content {
@@ -33,11 +37,15 @@ RenderFrameHostImpl* RenderFrameHostImpl::FromID(
RenderFrameHostImpl::RenderFrameHostImpl(
RenderViewHostImpl* render_view_host,
+ RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
+ FrameTreeNode* frame_tree_node,
int routing_id,
bool is_swapped_out)
: render_view_host_(render_view_host),
+ delegate_(delegate),
frame_tree_(frame_tree),
+ frame_tree_node_(frame_tree_node),
routing_id_(routing_id),
is_swapped_out_(is_swapped_out) {
GetProcess()->AddRoute(routing_id_, this);
@@ -50,7 +58,12 @@ RenderFrameHostImpl::~RenderFrameHostImpl() {
GetProcess()->RemoveRoute(routing_id_);
g_routing_id_frame_map.Get().erase(
RenderFrameHostID(GetProcess()->GetID(), routing_id_));
+ if (delegate_)
+ delegate_->RenderFrameDeleted(this);
+}
+int RenderFrameHostImpl::GetRoutingID() {
+ return routing_id_;
}
bool RenderFrameHostImpl::Send(IPC::Message* message) {
@@ -58,6 +71,9 @@ bool RenderFrameHostImpl::Send(IPC::Message* message) {
}
bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
+ if (delegate_->OnMessageReceived(this, msg))
+ return true;
+
bool handled = true;
bool msg_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok)
@@ -66,6 +82,13 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnDidStartProvisionalLoadForFrame)
IPC_END_MESSAGE_MAP_EX()
+ if (!msg_is_ok) {
+ // The message had a handler, but its de-serialization failed.
+ // Kill the renderer.
+ RecordAction(UserMetricsAction("BadMessageTerminate_RFH"));
+ GetProcess()->ReceivedBadMessage();
+ }
+
return handled;
}
@@ -83,12 +106,14 @@ void RenderFrameHostImpl::OnCreateChildFrame(int new_frame_routing_id,
int64 parent_frame_id,
int64 frame_id,
const std::string& frame_name) {
- frame_tree_->AddFrame(new_frame_routing_id, parent_frame_id, frame_id,
- frame_name);
+ RenderFrameHostImpl* new_frame = frame_tree_->AddFrame(
+ new_frame_routing_id, parent_frame_id, frame_id, frame_name);
+ if (delegate_)
+ delegate_->RenderFrameCreated(new_frame);
}
void RenderFrameHostImpl::OnDetach(int64 parent_frame_id, int64 frame_id) {
- frame_tree_->RemoveFrame(parent_frame_id, frame_id);
+ frame_tree_->RemoveFrame(this, parent_frame_id, frame_id);
}
void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame(
@@ -96,8 +121,8 @@ void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame(
int64 parent_frame_id,
bool is_main_frame,
const GURL& url) {
- render_view_host_->OnDidStartProvisionalLoadForFrame(
- frame_id, parent_frame_id, is_main_frame, url);
+ frame_tree_node_->navigator()->DidStartProvisionalLoad(
+ this, frame_id, parent_frame_id, is_main_frame, url);
}
} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 3c5e3acef2..2822724adf 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -13,9 +13,15 @@
class GURL;
+namespace base {
+class FilePath;
+}
+
namespace content {
class FrameTree;
+class FrameTreeNode;
+class RenderFrameHostDelegate;
class RenderProcessHost;
class RenderViewHostImpl;
@@ -25,6 +31,9 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
virtual ~RenderFrameHostImpl();
+ // RenderFrameHost
+ virtual int GetRoutingID() OVERRIDE;
+
// IPC::Sender
virtual bool Send(IPC::Message* msg) OVERRIDE;
@@ -39,9 +48,8 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
int64 frame_id,
const std::string& frame_name);
- RenderViewHostImpl* render_view_host() {
- return render_view_host_;
- }
+ RenderViewHostImpl* render_view_host() { return render_view_host_; }
+ RenderFrameHostDelegate* delegate() { return delegate_; }
protected:
friend class RenderFrameHostFactory;
@@ -50,11 +58,15 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
// should be the abstraction needed here, but we need RenderViewHost to pass
// into WebContentsObserver::FrameDetached for now.
RenderFrameHostImpl(RenderViewHostImpl* render_view_host,
+ RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
+ FrameTreeNode* frame_tree_node,
int routing_id,
bool is_swapped_out);
private:
+ friend class TestRenderViewHost;
+
// IPC Message handlers.
void OnDetach(int64 parent_frame_id, int64 frame_id);
void OnDidStartProvisionalLoadForFrame(int64 frame_id,
@@ -67,10 +79,16 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost {
// TODO(nasko): This should be removed and replaced by RenderProcessHost.
RenderViewHostImpl* render_view_host_; // Not owned.
+ RenderFrameHostDelegate* delegate_;
+
// Reference to the whole frame tree that this RenderFrameHost belongs too.
// Allows this RenderFrameHost to add and remove nodes in response to
// messages from the renderer requesting DOM manipulation.
FrameTree* frame_tree_;
+
+ // The FrameTreeNode which this RenderFrameHostImpl is hosted in.
+ FrameTreeNode* frame_tree_node_;
+
int routing_id_;
bool is_swapped_out_;
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 4e64342eac..8b7448d1a3 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -57,11 +57,13 @@ RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams(
RenderFrameHostManager::PendingNavigationParams::~PendingNavigationParams() {}
RenderFrameHostManager::RenderFrameHostManager(
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
Delegate* delegate)
: delegate_(delegate),
cross_navigation_pending_(false),
+ render_frame_delegate_(render_frame_delegate),
render_view_delegate_(render_view_delegate),
render_widget_delegate_(render_widget_delegate),
render_view_host_(NULL),
@@ -98,8 +100,8 @@ void RenderFrameHostManager::Init(BrowserContext* browser_context,
site_instance = SiteInstance::Create(browser_context);
render_view_host_ = static_cast<RenderViewHostImpl*>(
RenderViewHostFactory::Create(
- site_instance, render_view_delegate_, render_widget_delegate_,
- routing_id, main_frame_routing_id, false,
+ site_instance, render_view_delegate_, render_frame_delegate_,
+ render_widget_delegate_, routing_id, main_frame_routing_id, false,
delegate_->IsHidden()));
render_view_host_->AttachToFrameTree();
@@ -745,6 +747,7 @@ int RenderFrameHostManager::CreateRenderView(
new_render_view_host = static_cast<RenderViewHostImpl*>(
RenderViewHostFactory::Create(instance,
render_view_delegate_,
+ render_frame_delegate_,
render_widget_delegate_,
MSG_ROUTING_NONE,
MSG_ROUTING_NONE,
@@ -783,9 +786,13 @@ bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
render_view_host->AllowBindings(pending_web_ui()->GetBindings());
} else {
// Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
- // process.
- CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- render_view_host->GetProcess()->GetID()));
+ // process unless it's swapped out.
+ RenderViewHostImpl* rvh_impl =
+ static_cast<RenderViewHostImpl*>(render_view_host);
+ if (!rvh_impl->is_swapped_out()) {
+ CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ render_view_host->GetProcess()->GetID()));
+ }
}
return delegate_->CreateRenderViewForRenderManager(render_view_host,
@@ -799,6 +806,13 @@ void RenderFrameHostManager::CommitPending() {
// this triggers won't be able to figure out what's going on.
bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
+ // We expect SwapOutOldPage to have canceled any modal dialogs and told the
+ // renderer to suppress any further dialogs until it is swapped out. However,
+ // crash reports indicate that it's still possible for modal dialogs to exist
+ // at this point, which poses a risk if we delete their RenderViewHost below.
+ // Cancel them again to be safe. http://crbug.com/324320.
+ delegate_->CancelModalDialogsForRenderManager();
+
// Next commit the Web UI, if any. Either replace |web_ui_| with
// |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
// leave |web_ui_| as is if reusing it.
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index 78ca04aefe..94a4998b62 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -23,6 +23,7 @@ class InterstitialPageImpl;
class NavigationControllerImpl;
class NavigationEntry;
class NavigationEntryImpl;
+class RenderFrameHostDelegate;
class RenderFrameHostManagerTest;
class RenderViewHost;
class RenderViewHostImpl;
@@ -113,6 +114,7 @@ class CONTENT_EXPORT RenderFrameHostManager
//
// You must call Init() before using this class.
RenderFrameHostManager(
+ RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
Delegate* delegate);
@@ -356,6 +358,7 @@ class CONTENT_EXPORT RenderFrameHostManager
// Implemented by the owner of this class, these delegates are installed into
// all the RenderViewHosts that we create.
+ RenderFrameHostDelegate* render_frame_delegate_;
RenderViewHostDelegate* render_view_delegate_;
RenderWidgetHostDelegate* render_widget_delegate_;
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 9a4b004be3..2ba5fb8493 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -6,7 +6,6 @@
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/render_frame_host_manager.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/view_messages.h"
@@ -28,6 +27,7 @@
#include "content/public/test/test_notification_tracker.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -260,7 +260,7 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
contents()->GetRenderManagerForTesting()->current_host());
// Send an update title message and make sure it works.
- const string16 ntp_title = ASCIIToUTF16("NTP Title");
+ const base::string16 ntp_title = ASCIIToUTF16("NTP Title");
blink::WebTextDirection direction = blink::WebTextDirectionLeftToRight;
EXPECT_TRUE(ntp_rvh->OnMessageReceived(
ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction)));
@@ -288,7 +288,7 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
dest_rvh->SendNavigate(101, kDestUrl);
// The new RVH should be able to update its title.
- const string16 dest_title = ASCIIToUTF16("Google");
+ const base::string16 dest_title = ASCIIToUTF16("Google");
EXPECT_TRUE(dest_rvh->OnMessageReceived(
ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 101, dest_title,
direction)));
@@ -308,9 +308,9 @@ TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
MockRenderProcessHost* ntp_process_host =
static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess());
ntp_process_host->sink().ClearMessages();
- const string16 msg = ASCIIToUTF16("Message");
+ const base::string16 msg = ASCIIToUTF16("Message");
bool result = false;
- string16 unused;
+ base::string16 unused;
ViewHostMsg_RunBeforeUnloadConfirm before_unload_msg(
rvh()->GetRoutingID(), kChromeURL, msg, false, &result, &unused);
// Enable pumping for check in BrowserMessageFilter::CheckCanDispatchOnUI.
@@ -568,7 +568,7 @@ TEST_F(RenderFrameHostManagerTest, Init) {
scoped_ptr<TestWebContents> web_contents(
TestWebContents::Create(browser_context(), instance));
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
@@ -594,7 +594,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
// Create.
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
@@ -604,7 +604,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(
NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(),
- string16() /* title */, PAGE_TRANSITION_TYPED,
+ base::string16() /* title */, PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
host = manager.Navigate(entry1);
@@ -626,7 +626,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
NavigationEntryImpl entry2(
NULL /* instance */, -1 /* page_id */, kUrl2,
Referrer(kUrl1, blink::WebReferrerPolicyDefault),
- string16() /* title */, PAGE_TRANSITION_LINK,
+ base::string16() /* title */, PAGE_TRANSITION_LINK,
true /* is_renderer_init */);
host = manager.Navigate(entry2);
@@ -646,7 +646,7 @@ TEST_F(RenderFrameHostManagerTest, Navigate) {
NavigationEntryImpl entry3(
NULL /* instance */, -1 /* page_id */, kUrl3,
Referrer(kUrl2, blink::WebReferrerPolicyDefault),
- string16() /* title */, PAGE_TRANSITION_LINK,
+ base::string16() /* title */, PAGE_TRANSITION_LINK,
false /* is_renderer_init */);
host = manager.Navigate(entry3);
@@ -686,14 +686,14 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyReNavigation) {
// Create.
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
// 1) The first navigation. --------------------------
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHost* host = manager.Navigate(entry1);
@@ -721,7 +721,7 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyReNavigation) {
const GURL kUrl2("http://www.example.com");
NavigationEntryImpl entry2(
NULL /* instance */, -1 /* page_id */, kUrl2, Referrer(),
- string16() /* title */, PAGE_TRANSITION_TYPED,
+ base::string16() /* title */, PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHostImpl* host2 = static_cast<RenderViewHostImpl*>(
manager.Navigate(entry2));
@@ -772,7 +772,7 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyReNavigation) {
// 3) Cross-site navigate to next site before 2) has committed. --------------
const GURL kUrl3("http://webkit.org/");
NavigationEntryImpl entry3(NULL /* instance */, -1 /* page_id */, kUrl3,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
test_process_host->sink().ClearMessages();
@@ -829,14 +829,14 @@ TEST_F(RenderFrameHostManagerTest, WebUI) {
scoped_ptr<TestWebContents> web_contents(
TestWebContents::Create(browser_context(), instance));
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
EXPECT_FALSE(manager.current_host()->IsRenderViewLive());
const GURL kUrl("chrome://foo");
NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHost* host = manager.Navigate(entry);
@@ -876,16 +876,16 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
scoped_ptr<TestWebContents> web_contents1(
TestWebContents::Create(browser_context(), blank_instance));
RenderFrameHostManager manager1(web_contents1.get(), web_contents1.get(),
- web_contents1.get());
+ web_contents1.get(), web_contents1.get());
manager1.Init(
browser_context(), blank_instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
// Test the case that new RVH is considered live.
- manager1.current_host()->CreateRenderView(string16(), -1, -1);
+ manager1.current_host()->CreateRenderView(base::string16(), -1, -1);
// Navigate to a WebUI page.
const GURL kUrl1("chrome://foo");
NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHost* host1 = manager1.Navigate(entry1);
@@ -906,16 +906,16 @@ TEST_F(RenderFrameHostManagerTest, WebUIInNewTab) {
scoped_ptr<TestWebContents> web_contents2(
TestWebContents::Create(browser_context(), webui_instance));
RenderFrameHostManager manager2(web_contents2.get(), web_contents2.get(),
- web_contents2.get());
+ web_contents2.get(), web_contents2.get());
manager2.Init(
browser_context(), webui_instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
// Make sure the new RVH is considered live. This is usually done in
// RenderWidgetHost::Init when opening a new tab from a link.
- manager2.current_host()->CreateRenderView(string16(), -1, -1);
+ manager2.current_host()->CreateRenderView(base::string16(), -1, -1);
const GURL kUrl2("chrome://foo/bar");
NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_LINK,
true /* is_renderer_init */);
RenderViewHost* host2 = manager2.Navigate(entry2);
@@ -1107,7 +1107,7 @@ TEST_F(RenderFrameHostManagerTest, CleanUpSwappedOutRVHOnProcessCrash) {
contents()->SetOpener(opener1.get());
// Make sure the new opener RVH is considered live.
- opener1_manager->current_host()->CreateRenderView(string16(), -1, -1);
+ opener1_manager->current_host()->CreateRenderView(base::string16(), -1, -1);
// Use a cross-process navigation in the opener to swap out the old RVH.
EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost(
@@ -1192,7 +1192,7 @@ TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
// Create.
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
@@ -1202,7 +1202,7 @@ TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(
NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(),
- string16() /* title */, PAGE_TRANSITION_TYPED,
+ base::string16() /* title */, PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
host = manager.Navigate(entry1);
@@ -1225,7 +1225,7 @@ TEST_F(RenderFrameHostManagerTest, NoSwapOnGuestNavigations) {
NavigationEntryImpl entry2(
NULL /* instance */, -1 /* page_id */, kUrl2,
Referrer(kUrl1, blink::WebReferrerPolicyDefault),
- string16() /* title */, PAGE_TRANSITION_LINK,
+ base::string16() /* title */, PAGE_TRANSITION_LINK,
true /* is_renderer_init */);
host = manager.Navigate(entry2);
@@ -1257,14 +1257,14 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
// Create.
RenderFrameHostManager manager(web_contents.get(), web_contents.get(),
- web_contents.get());
+ web_contents.get(), web_contents.get());
manager.Init(browser_context(), instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE);
// 1) The first navigation. --------------------------
const GURL kUrl1("http://www.google.com/");
NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1,
- Referrer(), string16() /* title */,
+ Referrer(), base::string16() /* title */,
PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHost* host = manager.Navigate(entry1);
@@ -1291,7 +1291,7 @@ TEST_F(RenderFrameHostManagerTest, NavigateWithEarlyClose) {
const GURL kUrl2("http://www.example.com");
NavigationEntryImpl entry2(
NULL /* instance */, -1 /* page_id */, kUrl2, Referrer(),
- string16() /* title */, PAGE_TRANSITION_TYPED,
+ base::string16() /* title */, PAGE_TRANSITION_TYPED,
false /* is_renderer_init */);
RenderViewHostImpl* host2 = static_cast<RenderViewHostImpl*>(
manager.Navigate(entry2));
diff --git a/content/browser/frame_host/test_render_frame_host.cc b/content/browser/frame_host/test_render_frame_host.cc
deleted file mode 100644
index 040b232c40..0000000000
--- a/content/browser/frame_host/test_render_frame_host.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/frame_host/test_render_frame_host.h"
-
-namespace content {
-
-TestRenderFrameHost::TestRenderFrameHost(RenderViewHostImpl* render_view_host,
- FrameTree* frame_tree,
- int routing_id,
- bool is_swapped_out)
- : RenderFrameHostImpl(render_view_host,
- frame_tree,
- routing_id,
- is_swapped_out) {}
-
-TestRenderFrameHost::~TestRenderFrameHost() {}
-
-} // namespace content
diff --git a/content/browser/frame_host/test_render_frame_host.h b/content/browser/frame_host/test_render_frame_host.h
deleted file mode 100644
index 18055d67d1..0000000000
--- a/content/browser/frame_host/test_render_frame_host.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_FRAME_HOST_TEST_RENDER_FRAME_HOST_H_
-#define CONTENT_BROWSER_FRAME_HOST_TEST_RENDER_FRAME_HOST_H_
-
-#include "base/basictypes.h"
-#include "content/browser/frame_host/render_frame_host_impl.h"
-
-namespace content {
-
-class TestRenderFrameHost : public RenderFrameHostImpl {
- public:
- TestRenderFrameHost(RenderViewHostImpl* render_view_host,
- FrameTree* frame_tree,
- int routing_id,
- bool is_swapped_out);
- virtual ~TestRenderFrameHost();
-
- // TODO(nick): As necessary for testing, override behavior of RenderFrameHost
- // here.
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TestRenderFrameHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_FRAME_HOST_TEST_RENDER_FRAME_HOST_H_
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
index ba048aea88..d466dde4b0 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -186,8 +186,8 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
mapper ? "STANDARD GAMEPAD " : "",
vendor_id,
product_id);
- TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id);
- string16 tmp16 = UTF8ToUTF16(id);
+ base::TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id);
+ base::string16 tmp16 = UTF8ToUTF16(id);
memset(pad.id, 0, sizeof(pad.id));
tmp16.copy(pad.id, arraysize(pad.id) - 1);
diff --git a/content/browser/geolocation/OWNERS b/content/browser/geolocation/OWNERS
index 62bcb071e2..df10cf46d5 100644
--- a/content/browser/geolocation/OWNERS
+++ b/content/browser/geolocation/OWNERS
@@ -1,7 +1,3 @@
-# Reviewers:
bulach@chromium.org
mvanouwerkerk@chromium.org
timvolodine@chromium.org
-
-# Just owners:
-joth@chromium.org
diff --git a/content/browser/geolocation/fake_access_token_store.cc b/content/browser/geolocation/fake_access_token_store.cc
index 9f9f61ba7f..0e5fe40128 100644
--- a/content/browser/geolocation/fake_access_token_store.cc
+++ b/content/browser/geolocation/fake_access_token_store.cc
@@ -45,7 +45,7 @@ void FakeAccessTokenStore::DefaultLoadAccessTokens(
}
void FakeAccessTokenStore::DefaultSaveAccessToken(
- const GURL& server_url, const string16& access_token) {
+ const GURL& server_url, const base::string16& access_token) {
DCHECK(server_url.is_valid());
access_token_set_[server_url] = access_token;
}
diff --git a/content/browser/geolocation/fake_access_token_store.h b/content/browser/geolocation/fake_access_token_store.h
index 4d0867bf0b..30a01859d1 100644
--- a/content/browser/geolocation/fake_access_token_store.h
+++ b/content/browser/geolocation/fake_access_token_store.h
@@ -23,12 +23,13 @@ class FakeAccessTokenStore : public AccessTokenStore {
MOCK_METHOD1(LoadAccessTokens,
void(const LoadAccessTokensCallbackType& callback));
MOCK_METHOD2(SaveAccessToken,
- void(const GURL& server_url, const string16& access_token));
+ void(const GURL& server_url,
+ const base::string16& access_token));
void DefaultLoadAccessTokens(const LoadAccessTokensCallbackType& callback);
void DefaultSaveAccessToken(const GURL& server_url,
- const string16& access_token);
+ const base::string16& access_token);
AccessTokenSet access_token_set_;
LoadAccessTokensCallbackType callback_;
diff --git a/content/browser/geolocation/location_arbitrator_impl.cc b/content/browser/geolocation/location_arbitrator_impl.cc
index 37c34ee730..b8ed8c49bf 100644
--- a/content/browser/geolocation/location_arbitrator_impl.cc
+++ b/content/browser/geolocation/location_arbitrator_impl.cc
@@ -149,7 +149,7 @@ LocationProvider* LocationArbitratorImpl::NewNetworkLocationProvider(
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token) {
+ const base::string16& access_token) {
#if defined(OS_ANDROID)
// Android uses its own SystemLocationProvider.
return NULL;
diff --git a/content/browser/geolocation/location_arbitrator_impl.h b/content/browser/geolocation/location_arbitrator_impl.h
index 45910552e4..e756f5e15d 100644
--- a/content/browser/geolocation/location_arbitrator_impl.h
+++ b/content/browser/geolocation/location_arbitrator_impl.h
@@ -57,7 +57,7 @@ class CONTENT_EXPORT LocationArbitratorImpl : public LocationArbitrator {
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token);
+ const base::string16& access_token);
virtual LocationProvider* NewSystemLocationProvider();
virtual base::Time GetTimeNow() const;
diff --git a/content/browser/geolocation/location_arbitrator_impl_unittest.cc b/content/browser/geolocation/location_arbitrator_impl_unittest.cc
index 02df43172e..81df7a4326 100644
--- a/content/browser/geolocation/location_arbitrator_impl_unittest.cc
+++ b/content/browser/geolocation/location_arbitrator_impl_unittest.cc
@@ -85,7 +85,7 @@ class TestingLocationArbitrator : public LocationArbitratorImpl {
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token) OVERRIDE {
+ const base::string16& access_token) OVERRIDE {
return new MockLocationProvider(&cell_);
}
diff --git a/content/browser/geolocation/network_location_provider.cc b/content/browser/geolocation/network_location_provider.cc
index 678edb2409..efc68a7323 100644
--- a/content/browser/geolocation/network_location_provider.cc
+++ b/content/browser/geolocation/network_location_provider.cc
@@ -27,7 +27,7 @@ bool NetworkLocationProvider::PositionCache::CachePosition(
const WifiData& wifi_data,
const Geoposition& position) {
// Check that we can generate a valid key for the wifi data.
- string16 key;
+ base::string16 key;
if (!MakeKey(wifi_data, &key)) {
return false;
}
@@ -57,7 +57,7 @@ bool NetworkLocationProvider::PositionCache::CachePosition(
// the cached position if available, NULL otherwise.
const Geoposition* NetworkLocationProvider::PositionCache::FindPosition(
const WifiData& wifi_data) {
- string16 key;
+ base::string16 key;
if (!MakeKey(wifi_data, &key)) {
return NULL;
}
@@ -71,13 +71,13 @@ const Geoposition* NetworkLocationProvider::PositionCache::FindPosition(
// static
bool NetworkLocationProvider::PositionCache::MakeKey(
const WifiData& wifi_data,
- string16* key) {
+ base::string16* key) {
// Currently we use only WiFi data and base the key only on the MAC addresses.
DCHECK(key);
key->clear();
const size_t kCharsPerMacAddress = 6 * 3 + 1; // e.g. "11:22:33:44:55:66|"
key->reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress);
- const string16 separator(ASCIIToUTF16("|"));
+ const base::string16 separator(ASCIIToUTF16("|"));
for (WifiData::AccessPointDataSet::const_iterator iter =
wifi_data.access_point_data.begin();
iter != wifi_data.access_point_data.end();
@@ -96,7 +96,7 @@ LocationProviderBase* NewNetworkLocationProvider(
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token) {
+ const base::string16& access_token) {
return new NetworkLocationProvider(
access_token_store, context, url, access_token);
}
@@ -106,7 +106,7 @@ NetworkLocationProvider::NetworkLocationProvider(
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* url_context_getter,
const GURL& url,
- const string16& access_token)
+ const base::string16& access_token)
: access_token_store_(access_token_store),
wifi_data_provider_(NULL),
wifi_data_update_callback_(
@@ -163,7 +163,7 @@ void NetworkLocationProvider::WifiDataUpdateAvailable(
void NetworkLocationProvider::LocationResponseAvailable(
const Geoposition& position,
bool server_error,
- const string16& access_token,
+ const base::string16& access_token,
const WifiData& wifi_data) {
DCHECK(CalledOnValidThread());
// Record the position and update our cache.
diff --git a/content/browser/geolocation/network_location_provider.h b/content/browser/geolocation/network_location_provider.h
index d5f3e999d7..710fd3f4fa 100644
--- a/content/browser/geolocation/network_location_provider.h
+++ b/content/browser/geolocation/network_location_provider.h
@@ -54,12 +54,12 @@ class NetworkLocationProvider
// Makes the key for the map of cached positions, using a set of
// data. Returns true if a good key was generated, false otherwise.
static bool MakeKey(const WifiData& wifi_data,
- string16* key);
+ base::string16* key);
// The cache of positions. This is stored as a map keyed on a string that
// represents a set of data, and a list to provide
// least-recently-added eviction.
- typedef std::map<string16, Geoposition> CacheMap;
+ typedef std::map<base::string16, Geoposition> CacheMap;
CacheMap cache_;
typedef std::list<CacheMap::iterator> CacheAgeList;
CacheAgeList cache_age_list_; // Oldest first.
@@ -68,7 +68,7 @@ class NetworkLocationProvider
NetworkLocationProvider(AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token);
+ const base::string16& access_token);
virtual ~NetworkLocationProvider();
// LocationProvider implementation
@@ -92,7 +92,7 @@ class NetworkLocationProvider
void LocationResponseAvailable(const Geoposition& position,
bool server_error,
- const string16& access_token,
+ const base::string16& access_token,
const WifiData& wifi_data);
scoped_refptr<AccessTokenStore> access_token_store_;
@@ -111,7 +111,7 @@ class NetworkLocationProvider
// Cached value loaded from the token store or set by a previous server
// response, and sent in each subsequent network request.
- string16 access_token_;
+ base::string16 access_token_;
// The current best position estimate.
Geoposition position_;
@@ -138,7 +138,7 @@ CONTENT_EXPORT LocationProviderBase* NewNetworkLocationProvider(
AccessTokenStore* access_token_store,
net::URLRequestContextGetter* context,
const GURL& url,
- const string16& access_token);
+ const base::string16& access_token);
} // namespace content
diff --git a/content/browser/geolocation/network_location_request.cc b/content/browser/geolocation/network_location_request.cc
index 2e269b38a6..3ed709218f 100644
--- a/content/browser/geolocation/network_location_request.cc
+++ b/content/browser/geolocation/network_location_request.cc
@@ -72,7 +72,7 @@ GURL FormRequestURL(const GURL& url);
void FormUploadData(const WifiData& wifi_data,
const base::Time& timestamp,
- const string16& access_token,
+ const base::string16& access_token,
std::string* upload_data);
// Attempts to extract a position from the response. Detects and indicates
@@ -83,7 +83,7 @@ void GetLocationFromResponse(bool http_post_result,
const base::Time& timestamp,
const GURL& server_url,
Geoposition* position,
- string16* access_token);
+ base::string16* access_token);
// Parses the server response body. Returns true if parsing was successful.
// Sets |*position| to the parsed location if a valid fix was received,
@@ -91,7 +91,7 @@ void GetLocationFromResponse(bool http_post_result,
bool ParseServerResponse(const std::string& response_body,
const base::Time& timestamp,
Geoposition* position,
- string16* access_token);
+ base::string16* access_token);
void AddWifiData(const WifiData& wifi_data,
int age_milliseconds,
base::DictionaryValue* request);
@@ -111,7 +111,7 @@ NetworkLocationRequest::NetworkLocationRequest(
NetworkLocationRequest::~NetworkLocationRequest() {
}
-bool NetworkLocationRequest::MakeRequest(const string16& access_token,
+bool NetworkLocationRequest::MakeRequest(const base::string16& access_token,
const WifiData& wifi_data,
const base::Time& timestamp) {
RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_REQUEST_START);
@@ -150,7 +150,7 @@ void NetworkLocationRequest::OnURLFetchComplete(
RecordUmaResponseCode(response_code);
Geoposition position;
- string16 access_token;
+ base::string16 access_token;
std::string data;
source->GetResponseAsString(&data);
GetLocationFromResponse(status.is_success(),
@@ -207,7 +207,7 @@ GURL FormRequestURL(const GURL& url) {
void FormUploadData(const WifiData& wifi_data,
const base::Time& timestamp,
- const string16& access_token,
+ const base::string16& access_token,
std::string* upload_data) {
int age = kint32min; // Invalid so AddInteger() will ignore.
if (!timestamp.is_null()) {
@@ -291,7 +291,7 @@ void GetLocationFromResponse(bool http_post_result,
const base::Time& timestamp,
const GURL& server_url,
Geoposition* position,
- string16* access_token) {
+ base::string16* access_token) {
DCHECK(position);
DCHECK(access_token);
@@ -351,7 +351,7 @@ bool GetAsDouble(const base::DictionaryValue& object,
bool ParseServerResponse(const std::string& response_body,
const base::Time& timestamp,
Geoposition* position,
- string16* access_token) {
+ base::string16* access_token) {
DCHECK(position);
DCHECK(!position->Validate());
DCHECK(position->error_code == Geoposition::ERROR_CODE_NONE);
diff --git a/content/browser/geolocation/network_location_request.h b/content/browser/geolocation/network_location_request.h
index 38aaf3e6ce..6fea08b8bd 100644
--- a/content/browser/geolocation/network_location_request.h
+++ b/content/browser/geolocation/network_location_request.h
@@ -33,7 +33,7 @@ class NetworkLocationRequest : private net::URLFetcherDelegate {
// server or network error - either no response or a 500 error code.
typedef base::Callback<void(const Geoposition& /* position */,
bool /* server_error */,
- const string16& /* access_token */,
+ const base::string16& /* access_token */,
const WifiData& /* wifi_data */)>
LocationResponseCallback;
@@ -45,7 +45,7 @@ class NetworkLocationRequest : private net::URLFetcherDelegate {
// Makes a new request. Returns true if the new request was successfully
// started. In all cases, any currently pending request will be canceled.
- bool MakeRequest(const string16& access_token,
+ bool MakeRequest(const base::string16& access_token,
const WifiData& wifi_data,
const base::Time& timestamp);
diff --git a/content/browser/geolocation/wifi_data.h b/content/browser/geolocation/wifi_data.h
index a24e42e2ac..72bc3065ab 100644
--- a/content/browser/geolocation/wifi_data.h
+++ b/content/browser/geolocation/wifi_data.h
@@ -19,11 +19,11 @@ struct CONTENT_EXPORT AccessPointData {
~AccessPointData();
// MAC address, formatted as per MacAddressAsString16.
- string16 mac_address;
+ base::string16 mac_address;
int radio_signal_strength; // Measured in dBm
int channel;
int signal_to_noise; // Ratio in dB
- string16 ssid; // Network identifier
+ base::string16 ssid; // Network identifier
};
// This is to allow AccessPointData to be used in std::set. We order
diff --git a/content/browser/geolocation/wifi_data_provider_common.cc b/content/browser/geolocation/wifi_data_provider_common.cc
index 31f969c3a3..9c2cbae234 100644
--- a/content/browser/geolocation/wifi_data_provider_common.cc
+++ b/content/browser/geolocation/wifi_data_provider_common.cc
@@ -10,7 +10,7 @@
namespace content {
-string16 MacAddressAsString16(const uint8 mac_as_int[6]) {
+base::string16 MacAddressAsString16(const uint8 mac_as_int[6]) {
// mac_as_int is big-endian. Write in byte chunks.
// Format is XX-XX-XX-XX-XX-XX.
static const char* const kMacFormatString =
diff --git a/content/browser/geolocation/wifi_data_provider_common.h b/content/browser/geolocation/wifi_data_provider_common.h
index c42b4c2a85..befdb69211 100644
--- a/content/browser/geolocation/wifi_data_provider_common.h
+++ b/content/browser/geolocation/wifi_data_provider_common.h
@@ -18,7 +18,7 @@
namespace content {
// Converts a MAC address stored as an array of uint8 to a string.
-string16 MacAddressAsString16(const uint8 mac_as_int[6]);
+base::string16 MacAddressAsString16(const uint8 mac_as_int[6]);
// Base class to promote code sharing between platform specific wifi data
// providers. It's optional for specific platforms to derive this, but if they
diff --git a/content/browser/geolocation/wifi_data_provider_win.cc b/content/browser/geolocation/wifi_data_provider_win.cc
index 8efb191845..ed69865fbd 100644
--- a/content/browser/geolocation/wifi_data_provider_win.cc
+++ b/content/browser/geolocation/wifi_data_provider_win.cc
@@ -127,15 +127,15 @@ class WindowsNdisApi : public WifiDataProviderCommon::WlanApiInterface {
private:
static bool GetInterfacesNDIS(
- std::vector<string16>* interface_service_names_out);
+ std::vector<base::string16>* interface_service_names_out);
// Swaps in content of the vector passed
- explicit WindowsNdisApi(std::vector<string16>* interface_service_names);
+ explicit WindowsNdisApi(std::vector<base::string16>* interface_service_names);
bool GetInterfaceDataNDIS(HANDLE adapter_handle,
WifiData::AccessPointDataSet* data);
// NDIS variables.
- std::vector<string16> interface_service_names_;
+ std::vector<base::string16> interface_service_names_;
// Remembers scan result buffer size across calls.
int oid_buffer_size_;
@@ -144,9 +144,9 @@ class WindowsNdisApi : public WifiDataProviderCommon::WlanApiInterface {
// Extracts data for an access point and converts to Gears format.
bool GetNetworkData(const WLAN_BSS_ENTRY& bss_entry,
AccessPointData* access_point_data);
-bool UndefineDosDevice(const string16& device_name);
-bool DefineDosDeviceIfNotExists(const string16& device_name);
-HANDLE GetFileHandle(const string16& device_name);
+bool UndefineDosDevice(const base::string16& device_name);
+bool DefineDosDeviceIfNotExists(const base::string16& device_name);
+HANDLE GetFileHandle(const base::string16& device_name);
// Makes the OID query and returns a Win32 error code.
int PerformQuery(HANDLE adapter_handle,
BYTE* buffer,
@@ -155,7 +155,7 @@ int PerformQuery(HANDLE adapter_handle,
bool ResizeBuffer(int requested_size, scoped_ptr_malloc<BYTE>* buffer);
// Gets the system directory and appends a trailing slash if not already
// present.
-bool GetSystemDirectory(string16* path);
+bool GetSystemDirectory(base::string16* path);
} // namespace
WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
@@ -202,12 +202,12 @@ WindowsWlanApi* WindowsWlanApi::Create() {
if (base::win::GetVersion() < base::win::VERSION_VISTA)
return NULL;
// We use an absolute path to load the DLL to avoid DLL preloading attacks.
- string16 system_directory;
+ base::string16 system_directory;
if (!GetSystemDirectory(&system_directory)) {
return NULL;
}
DCHECK(!system_directory.empty());
- string16 dll_path = system_directory + L"wlanapi.dll";
+ base::string16 dll_path = system_directory + L"wlanapi.dll";
HINSTANCE library = LoadLibraryEx(dll_path.c_str(),
NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -359,7 +359,7 @@ int WindowsWlanApi::GetInterfaceDataWLAN(
// WindowsNdisApi
WindowsNdisApi::WindowsNdisApi(
- std::vector<string16>* interface_service_names)
+ std::vector<base::string16>* interface_service_names)
: oid_buffer_size_(kInitialBufferSize) {
DCHECK(!interface_service_names->empty());
interface_service_names_.swap(*interface_service_names);
@@ -369,7 +369,7 @@ WindowsNdisApi::~WindowsNdisApi() {
}
WindowsNdisApi* WindowsNdisApi::Create() {
- std::vector<string16> interface_service_names;
+ std::vector<base::string16> interface_service_names;
if (GetInterfacesNDIS(&interface_service_names)) {
return new WindowsNdisApi(&interface_service_names);
}
@@ -412,7 +412,7 @@ bool WindowsNdisApi::GetAccessPointData(WifiData::AccessPointDataSet* data) {
}
bool WindowsNdisApi::GetInterfacesNDIS(
- std::vector<string16>* interface_service_names_out) {
+ std::vector<base::string16>* interface_service_names_out) {
HKEY network_cards_key = NULL;
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
@@ -530,18 +530,18 @@ bool GetNetworkData(const WLAN_BSS_ENTRY& bss_entry,
return true;
}
-bool UndefineDosDevice(const string16& device_name) {
+bool UndefineDosDevice(const base::string16& device_name) {
// We remove only the mapping we use, that is \Device\<device_name>.
- string16 target_path = L"\\Device\\" + device_name;
+ base::string16 target_path = L"\\Device\\" + device_name;
return DefineDosDevice(
DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
device_name.c_str(),
target_path.c_str()) == TRUE;
}
-bool DefineDosDeviceIfNotExists(const string16& device_name) {
+bool DefineDosDeviceIfNotExists(const base::string16& device_name) {
// We create a DOS device name for the device at \Device\<device_name>.
- string16 target_path = L"\\Device\\" + device_name;
+ base::string16 target_path = L"\\Device\\" + device_name;
TCHAR target[kStringLength];
if (QueryDosDevice(device_name.c_str(), target, kStringLength) > 0 &&
@@ -565,10 +565,10 @@ bool DefineDosDeviceIfNotExists(const string16& device_name) {
target_path.compare(target) == 0;
}
-HANDLE GetFileHandle(const string16& device_name) {
+HANDLE GetFileHandle(const base::string16& device_name) {
// We access a device with DOS path \Device\<device_name> at
// \\.\<device_name>.
- string16 formatted_device_name = L"\\\\.\\" + device_name;
+ base::string16 formatted_device_name = L"\\\\.\\" + device_name;
return CreateFile(formatted_device_name.c_str(),
GENERIC_READ,
@@ -610,7 +610,7 @@ bool ResizeBuffer(int requested_size, scoped_ptr_malloc<BYTE>* buffer) {
return buffer != NULL;
}
-bool GetSystemDirectory(string16* path) {
+bool GetSystemDirectory(base::string16* path) {
DCHECK(path);
// Return value includes terminating NULL.
int buffer_size = ::GetSystemDirectory(NULL, 0);
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index 947499967e..d0ce8b4806 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -11,9 +11,10 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/common/child_process_host_impl.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_client.h"
#include "ipc/ipc_forwarding_message_filter.h"
@@ -134,6 +135,10 @@ void BrowserGpuChannelHostFactory::EstablishRequest::Cancel() {
finished_ = true;
}
+bool BrowserGpuChannelHostFactory::CanUseForTesting() {
+ return GpuDataManager::GetInstance()->GpuAccessAllowed(NULL);
+}
+
void BrowserGpuChannelHostFactory::Initialize(bool establish_gpu_channel) {
DCHECK(!instance_);
instance_ = new BrowserGpuChannelHostFactory(establish_gpu_channel);
@@ -355,7 +360,6 @@ void BrowserGpuChannelHostFactory::GpuChannelEstablished() {
GetContentClient()->SetGpuInfo(pending_request_->gpu_info());
gpu_channel_ = GpuChannelHost::Create(this,
pending_request_->gpu_host_id(),
- gpu_client_id_,
pending_request_->gpu_info(),
pending_request_->channel_handle());
gpu_host_id_ = pending_request_->gpu_host_id();
@@ -381,11 +385,12 @@ scoped_ptr<gfx::GpuMemoryBuffer>
if (!shm->CreateAnonymous(size))
return scoped_ptr<gfx::GpuMemoryBuffer>();
- return make_scoped_ptr<gfx::GpuMemoryBuffer>(
- new GpuMemoryBufferImpl(shm.Pass(),
- width,
- height,
- internalformat));
+ scoped_ptr<GpuMemoryBufferImplShm> buffer(
+ new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat));
+ if (!buffer->InitializeFromSharedMemory(shm.Pass()))
+ return scoped_ptr<gfx::GpuMemoryBuffer>();
+
+ return buffer.PassAs<gfx::GpuMemoryBuffer>();
}
// static
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index 6f09e1429b..8b461e4aec 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -57,6 +57,10 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
void EstablishGpuChannel(CauseForGpuLaunch cause_for_gpu_launch,
const base::Closure& callback);
GpuChannelHost* GetGpuChannel();
+ int GetGpuChannelId() { return gpu_client_id_; }
+
+ // Used to skip GpuChannelHost tests when there can be no GPU process.
+ static bool CanUseForTesting();
private:
struct CreateRequest {
@@ -90,7 +94,7 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
base::WaitableEvent event_;
CauseForGpuLaunch cause_for_gpu_launch_;
- int gpu_client_id_;
+ const int gpu_client_id_;
int gpu_host_id_;
bool reused_gpu_process_;
IPC::ChannelHandle channel_handle_;
@@ -121,7 +125,7 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
int gpu_host_id,
scoped_refptr<IPC::ChannelProxy::MessageFilter> filter);
- int gpu_client_id_;
+ const int gpu_client_id_;
scoped_ptr<base::WaitableEvent> shutdown_event_;
scoped_refptr<GpuChannelHost> gpu_channel_;
int gpu_host_id_;
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index 916fcdec54..73af1304a4 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -24,14 +24,6 @@ struct GpuFeatureInfo {
bool fallback_to_software;
};
-// Determine if accelerated-2d-canvas is supported, which depends on whether
-// lose_context could happen.
-bool SupportsAccelerated2dCanvas() {
- if (GpuDataManagerImpl::GetInstance()->GetGPUInfo().can_lose_context)
- return false;
- return true;
-}
-
#if defined(OS_CHROMEOS)
const size_t kNumFeatures = 14;
#else
@@ -47,7 +39,8 @@ const GpuFeatureInfo GetGpuFeatureInfo(size_t index) {
manager->IsFeatureBlacklisted(
gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
- !SupportsAccelerated2dCanvas(),
+ !GpuDataManagerImpl::GetInstance()->
+ GetGPUInfo().SupportsAccelerated2dCanvas(),
"Accelerated 2D canvas is unavailable: either disabled at the command"
" line or not supported by the current system.",
true
@@ -140,6 +133,17 @@ const GpuFeatureInfo GetGpuFeatureInfo(size_t index) {
" or command line.",
true
},
+#if defined(ENABLE_WEBRTC)
+ {
+ "video_encode",
+ manager->IsFeatureBlacklisted(
+ gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
+ command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
+ "Accelerated video encode has been disabled, either via about:flags"
+ " or command line.",
+ true
+ },
+#endif
{
"video",
manager->IsFeatureBlacklisted(
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index b5b44ffdbb..86b63b4908 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -198,21 +198,6 @@ void UpdateStats(const gpu::GPUInfo& gpu_info,
gpu_info.gl_reset_notification_strategy);
}
-// Strip out the non-digital info; if after that, we get an empty string,
-// return "0".
-std::string ProcessVersionString(const std::string& raw_string) {
- const std::string valid_set = "0123456789.";
- size_t start_pos = raw_string.find_first_of(valid_set);
- if (start_pos == std::string::npos)
- return "0";
- size_t end_pos = raw_string.find_first_not_of(raw_string, start_pos);
- std::string version_string = raw_string.substr(
- start_pos, end_pos - start_pos);
- if (version_string.empty())
- return "0";
- return version_string;
-}
-
// Combine the integers into a string, seperated by ','.
std::string IntSetToString(const std::set<int>& list) {
std::string rt;
@@ -646,6 +631,11 @@ void GpuDataManagerImplPrivate::AppendRendererCommandLine(
if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
!command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
+#if defined(ENABLE_WEBRTC)
+ if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
+ !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding))
+ command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
+#endif
if (use_software_compositor_ &&
!command_line->HasSwitch(switches::kEnableSoftwareCompositing))
@@ -713,6 +703,12 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
!command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
}
+#if defined(ENABLE_WEBRTC)
+ if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
+ !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
+ command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
+ }
+#endif
#if defined(OS_WIN)
// DisplayLink 7.1 and earlier can cause the GPU process to crash on startup.
@@ -999,10 +995,6 @@ void GpuDataManagerImplPrivate::InitializeImpl(
const std::string& gpu_blacklist_json,
const std::string& gpu_driver_bug_list_json,
const gpu::GPUInfo& gpu_info) {
- std::string browser_version_string = ProcessVersionString(
- GetContentClient()->GetProduct());
- CHECK(!browser_version_string.empty());
-
const bool log_gpu_control_list_decisions =
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kLogGpuControlListDecisions);
@@ -1012,8 +1004,7 @@ void GpuDataManagerImplPrivate::InitializeImpl(
if (log_gpu_control_list_decisions)
gpu_blacklist_->enable_control_list_logging("gpu_blacklist");
bool success = gpu_blacklist_->LoadList(
- browser_version_string, gpu_blacklist_json,
- gpu::GpuControlList::kCurrentOsOnly);
+ gpu_blacklist_json, gpu::GpuControlList::kCurrentOsOnly);
DCHECK(success);
}
if (!gpu_driver_bug_list_json.empty()) {
@@ -1021,8 +1012,7 @@ void GpuDataManagerImplPrivate::InitializeImpl(
if (log_gpu_control_list_decisions)
gpu_driver_bug_list_->enable_control_list_logging("gpu_driver_bug_list");
bool success = gpu_driver_bug_list_->LoadList(
- browser_version_string, gpu_driver_bug_list_json,
- gpu::GpuControlList::kCurrentOsOnly);
+ gpu_driver_bug_list_json, gpu::GpuControlList::kCurrentOsOnly);
DCHECK(success);
}
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc
index f41160d761..ca2ccf9ee0 100644
--- a/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -10,6 +10,7 @@
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_switches.h"
#include "content/test/content_browser_test.h"
#include "ui/gl/gl_switches.h"
@@ -22,6 +23,9 @@ using content::WebGraphicsContext3DCommandBufferImpl;
class ContextTestBase : public content::ContentBrowserTest {
public:
virtual void SetUpOnMainThread() OVERRIDE {
+ if (!content::BrowserGpuChannelHostFactory::CanUseForTesting())
+ return;
+
if (!content::BrowserGpuChannelHostFactory::instance())
content::BrowserGpuChannelHostFactory::Initialize(true);
@@ -66,6 +70,9 @@ namespace content {
class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
public:
virtual void SetUpOnMainThread() OVERRIDE {
+ if (!content::BrowserGpuChannelHostFactory::CanUseForTesting())
+ return;
+
// Start all tests without a gpu channel so that the tests exercise a
// consistent codepath.
if (!content::BrowserGpuChannelHostFactory::instance())
@@ -128,6 +135,9 @@ class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
};
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
+ if (!context_)
+ return;
+
DCHECK(!IsChannelEstablished());
EstablishAndWait();
EXPECT_TRUE(GetGpuChannel() != NULL);
@@ -135,6 +145,9 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
EstablishAndTerminate) {
+ if (!context_)
+ return;
+
DCHECK(!IsChannelEstablished());
base::RunLoop run_loop;
GetFactory()->EstablishGpuChannel(
@@ -147,6 +160,9 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
}
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
+ if (!context_)
+ return;
+
DCHECK(!IsChannelEstablished());
scoped_refptr<GpuChannelHost> gpu_channel =
GetFactory()->EstablishGpuChannelSync(
@@ -162,6 +178,9 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
}
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CrashAndRecover) {
+ if (!context_)
+ return;
+
DCHECK(!IsChannelEstablished());
EstablishAndWait();
scoped_refptr<GpuChannelHost> host = GetGpuChannel();
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 26b33d45c9..1b7da1c8d7 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -48,6 +48,10 @@
#include "ui/surface/accelerated_surface_win.h"
#endif
+#if defined(USE_OZONE)
+#include "ui/ozone/ozone_switches.h"
+#endif
+
namespace content {
bool GpuProcessHost::gpu_enabled_ = true;
@@ -252,7 +256,7 @@ class GpuSandboxedProcessLauncherDelegate
#endif
if (cmd_line_->HasSwitch(switches::kEnableLogging)) {
- string16 log_file_path = logging::GetLogFileFullPath();
+ base::string16 log_file_path = logging::GetLogFileFullPath();
if (!log_file_path.empty()) {
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY,
@@ -1112,6 +1116,9 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
switches::kDisableImageTransportSurface,
switches::kDisableLogging,
switches::kDisableSeccompFilterSandbox,
+#if defined(ENABLE_WEBRTC)
+ switches::kDisableWebRtcHWEncoding,
+#endif
switches::kEnableLogging,
switches::kEnableShareGroupAsyncTextureUpload,
switches::kGpuStartupDialog,
@@ -1129,6 +1136,9 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
#if defined(USE_AURA)
switches::kUIPrioritizeInGpuProcess,
#endif
+#if defined(USE_OZONE)
+ switches::kOzonePlatform,
+#endif
};
cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
arraysize(kSwitchNames));
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index ae40d22846..e08a7b3c56 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -157,7 +157,7 @@ static void PutVarInt(LevelDBTransaction* transaction,
template <typename DBOrTransaction>
WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db,
const StringPiece& key,
- string16* found_string,
+ base::string16* found_string,
bool* found) {
std::string result;
*found = false;
@@ -172,7 +172,7 @@ WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db,
static void PutString(LevelDBTransaction* transaction,
const StringPiece& key,
- const string16& value) {
+ const base::string16& value) {
std::string buffer;
EncodeString(value, &buffer);
transaction->Put(key, &buffer);
@@ -513,7 +513,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII,
origin_url);
}
- if (!file_util::CreateDirectory(path_base)) {
+ if (!base::CreateDirectory(path_base)) {
LOG(ERROR) << "Unable to create IndexedDB database path "
<< path_base.AsUTF8Unsafe();
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY,
@@ -653,8 +653,8 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create(
return backing_store;
}
-std::vector<string16> IndexedDBBackingStore::GetDatabaseNames() {
- std::vector<string16> found_names;
+std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() {
+ std::vector<base::string16> found_names;
const std::string start_key =
DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_);
const std::string stop_key =
@@ -678,7 +678,7 @@ std::vector<string16> IndexedDBBackingStore::GetDatabaseNames() {
}
bool IndexedDBBackingStore::GetIDBDatabaseMetaData(
- const string16& name,
+ const base::string16& name,
IndexedDBDatabaseMetadata* metadata,
bool* found) {
const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
@@ -755,10 +755,11 @@ WARN_UNUSED_RESULT static bool GetNewDatabaseId(LevelDBTransaction* transaction,
return true;
}
-bool IndexedDBBackingStore::CreateIDBDatabaseMetaData(const string16& name,
- const string16& version,
- int64 int_version,
- int64* row_id) {
+bool IndexedDBBackingStore::CreateIDBDatabaseMetaData(
+ const base::string16& name,
+ const base::string16& version,
+ int64 int_version,
+ int64* row_id) {
scoped_refptr<LevelDBTransaction> transaction =
new LevelDBTransaction(db_.get());
@@ -811,7 +812,7 @@ static void DeleteRange(LevelDBTransaction* transaction,
transaction->Remove(it->Key());
}
-bool IndexedDBBackingStore::DeleteDatabase(const string16& name) {
+bool IndexedDBBackingStore::DeleteDatabase(const base::string16& name) {
IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
scoped_ptr<LevelDBWriteOnlyTransaction> transaction =
LevelDBWriteOnlyTransaction::Create(db_.get());
@@ -895,7 +896,7 @@ bool IndexedDBBackingStore::GetObjectStores(
// TODO(jsbell): Do this by direct key lookup rather than iteration, to
// simplify.
- string16 object_store_name;
+ base::string16 object_store_name;
{
StringPiece slice(it->Value());
if (!DecodeString(&slice, &object_store_name) || !slice.empty())
@@ -1049,7 +1050,7 @@ bool IndexedDBBackingStore::CreateObjectStore(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment) {
IDB_TRACE("IndexedDBBackingStore::CreateObjectStore");
@@ -1103,7 +1104,7 @@ bool IndexedDBBackingStore::DeleteObjectStore(
return false;
LevelDBTransaction* leveldb_transaction = transaction->transaction();
- string16 object_store_name;
+ base::string16 object_store_name;
bool found = false;
bool ok = GetString(
leveldb_transaction,
@@ -1473,7 +1474,7 @@ bool IndexedDBBackingStore::GetIndexes(
// TODO(jsbell): Do this by direct key lookup rather than iteration, to
// simplify.
int64 index_id = meta_data_key.IndexId();
- string16 index_name;
+ base::string16 index_name;
{
StringPiece slice(it->Value());
if (!DecodeString(&slice, &index_name) || !slice.empty())
@@ -1553,7 +1554,7 @@ bool IndexedDBBackingStore::CreateIndex(
int64 database_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool is_unique,
bool is_multi_entry) {
@@ -2022,7 +2023,7 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
}
// IndexedDBBackingStore::Cursor
- virtual std::string* Value() OVERRIDE {
+ virtual std::string* value() OVERRIDE {
NOTREACHED();
return NULL;
}
@@ -2079,7 +2080,7 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); }
// IndexedDBBackingStore::Cursor
- virtual std::string* Value() OVERRIDE { return &current_value_; }
+ virtual std::string* value() OVERRIDE { return &current_value_; }
virtual bool LoadCurrentRow() OVERRIDE;
protected:
@@ -2137,15 +2138,15 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); }
// IndexedDBBackingStore::Cursor
- virtual std::string* Value() OVERRIDE {
+ virtual std::string* value() OVERRIDE {
NOTREACHED();
return NULL;
}
virtual const IndexedDBKey& primary_key() const OVERRIDE {
return *primary_key_;
}
- virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier()
- const {
+ virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier()
+ const OVERRIDE {
NOTREACHED();
return record_identifier_;
}
@@ -2244,12 +2245,12 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); }
// IndexedDBBackingStore::Cursor
- virtual std::string* Value() OVERRIDE { return &current_value_; }
+ virtual std::string* value() OVERRIDE { return &current_value_; }
virtual const IndexedDBKey& primary_key() const OVERRIDE {
return *primary_key_;
}
- virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier()
- const {
+ virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier()
+ const OVERRIDE {
NOTREACHED();
return record_identifier_;
}
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h
index 9ea71f11ac..890f95ebdf 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -69,19 +69,19 @@ class CONTENT_EXPORT IndexedDBBackingStore
const GURL& origin_url,
LevelDBFactory* factory);
- virtual std::vector<string16> GetDatabaseNames();
- virtual bool GetIDBDatabaseMetaData(const string16& name,
+ virtual std::vector<base::string16> GetDatabaseNames();
+ virtual bool GetIDBDatabaseMetaData(const base::string16& name,
IndexedDBDatabaseMetadata* metadata,
bool* success) WARN_UNUSED_RESULT;
- virtual bool CreateIDBDatabaseMetaData(const string16& name,
- const string16& version,
+ virtual bool CreateIDBDatabaseMetaData(const base::string16& name,
+ const base::string16& version,
int64 int_version,
int64* row_id);
virtual bool UpdateIDBDatabaseIntVersion(
IndexedDBBackingStore::Transaction* transaction,
int64 row_id,
int64 int_version);
- virtual bool DeleteDatabase(const string16& name);
+ virtual bool DeleteDatabase(const base::string16& name);
bool GetObjectStores(int64 database_id,
IndexedDBDatabaseMetadata::ObjectStoreMap* map)
@@ -90,7 +90,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment);
virtual bool DeleteObjectStore(
@@ -160,7 +160,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
int64 database_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool is_unique,
bool is_multi_entry) WARN_UNUSED_RESULT;
@@ -226,7 +226,7 @@ class CONTENT_EXPORT IndexedDBBackingStore
virtual Cursor* Clone() = 0;
virtual const IndexedDBKey& primary_key() const;
- virtual std::string* Value() = 0;
+ virtual std::string* value() = 0;
virtual const RecordIdentifier& record_identifier() const;
virtual bool LoadCurrentRow() = 0;
@@ -279,10 +279,10 @@ class CONTENT_EXPORT IndexedDBBackingStore
class Transaction {
public:
explicit Transaction(IndexedDBBackingStore* backing_store);
- ~Transaction();
- void Begin();
- bool Commit();
- void Rollback();
+ virtual ~Transaction();
+ virtual void Begin();
+ virtual bool Commit();
+ virtual void Rollback();
void Reset() {
backing_store_ = NULL;
transaction_ = NULL;
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
index 396189e519..d3e82964af 100644
--- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -236,19 +236,19 @@ TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
}
TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
- const string16 database_name(ASCIIToUTF16("db1"));
+ const base::string16 database_name(ASCIIToUTF16("db1"));
int64 database_id;
- const string16 version(ASCIIToUTF16("old_string_version"));
+ const base::string16 version(ASCIIToUTF16("old_string_version"));
const int64 int_version = 9;
const int64 object_store_id = 99;
- const string16 object_store_name(ASCIIToUTF16("object_store1"));
+ const base::string16 object_store_name(ASCIIToUTF16("object_store1"));
const bool auto_increment = true;
const IndexedDBKeyPath object_store_key_path(
ASCIIToUTF16("object_store_key"));
const int64 index_id = 999;
- const string16 index_name(ASCIIToUTF16("index1"));
+ const base::string16 index_name(ASCIIToUTF16("index1"));
const bool unique = true;
const bool multi_entry = true;
const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 9fca832cc2..e979168e76 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -66,7 +66,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
if (hash)
url = GURL(url.spec() + hash);
- string16 expected_title16(ASCIIToUTF16(expected_string));
+ base::string16 expected_title16(ASCIIToUTF16(expected_string));
TitleWatcher title_watcher(shell->web_contents(), expected_title16);
NavigateToURL(shell, url);
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
@@ -234,7 +234,7 @@ static void CopyLevelDBToProfile(Shell* shell,
// If we don't create the destination directory first, the contents of the
// leveldb directory are copied directly into profile/IndexedDB instead of
// profile/IndexedDB/file__0.xxx/
- ASSERT_TRUE(file_util::CreateDirectory(dest));
+ ASSERT_TRUE(base::CreateDirectory(dest));
const bool kRecursive = true;
ASSERT_TRUE(base::CopyDirectory(test_data_dir,
context->data_path(),
@@ -342,7 +342,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {
base::FilePath log_file_path =
GetContext()->data_path().Append(leveldb_dir).Append(log_file);
int64 size;
- EXPECT_TRUE(file_util::GetFileSize(log_file_path, &size));
+ EXPECT_TRUE(base::GetFileSize(log_file_path, &size));
EXPECT_GT(size, 0);
}
@@ -399,7 +399,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ConnectionsClosedOnTabClose) {
NavigateAndWaitForTitle(new_shell, "version_change_blocked.html", "#tab2",
"setVersion(3) blocked");
- string16 expected_title16(ASCIIToUTF16("setVersion(3) complete"));
+ base::string16 expected_title16(ASCIIToUTF16("setVersion(3) complete"));
TitleWatcher title_watcher(new_shell->web_contents(), expected_title16);
base::KillProcess(
@@ -421,7 +421,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
GetContext(),
GURL("file:///")));
- string16 expected_title16(ASCIIToUTF16("connection closed"));
+ base::string16 expected_title16(ASCIIToUTF16("connection closed"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc
index 587b66f066..755551cec8 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -71,7 +71,7 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
dispatcher_host_ = NULL;
}
-void IndexedDBCallbacks::OnSuccess(const std::vector<string16>& value) {
+void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
DCHECK(dispatcher_host_.get());
DCHECK_EQ(kNoCursor, ipc_cursor_id_);
@@ -79,7 +79,7 @@ void IndexedDBCallbacks::OnSuccess(const std::vector<string16>& value) {
DCHECK_EQ(kNoDatabase, ipc_database_id_);
DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
- std::vector<string16> list;
+ std::vector<base::string16> list;
for (unsigned i = 0; i < value.size(); ++i)
list.push_back(value[i]);
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h
index 1ea0c0b4af..048b563bf2 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.h
+++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -51,7 +51,7 @@ class CONTENT_EXPORT IndexedDBCallbacks
virtual void OnError(const IndexedDBDatabaseError& error);
// IndexedDBFactory::GetDatabaseNames
- virtual void OnSuccess(const std::vector<string16>& string);
+ virtual void OnSuccess(const std::vector<base::string16>& string);
// IndexedDBFactory::Open / DeleteDatabase
virtual void OnBlocked(int64 existing_version);
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 37548c8ff7..e8ab70bbbf 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -23,6 +23,7 @@
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
#include "content/browser/indexed_db/indexed_db_quota_client.h"
+#include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/indexed_db_info.h"
@@ -106,6 +107,7 @@ IndexedDBContextImpl::IndexedDBContextImpl(
special_storage_policy_(special_storage_policy),
quota_manager_proxy_(quota_manager_proxy),
task_runner_(task_runner) {
+ IDB_TRACE("init");
if (!data_path.empty())
data_path_ = data_path.Append(kIndexedDBDirectory);
if (quota_manager_proxy) {
@@ -295,7 +297,7 @@ base::Time IndexedDBContextImpl::GetOriginLastModified(const GURL& origin_url) {
return base::Time();
base::FilePath idb_directory = GetFilePath(origin_url);
base::PlatformFileInfo file_info;
- if (!file_util::GetFileInfo(idb_directory, &file_info))
+ if (!base::GetFileInfo(idb_directory, &file_info))
return base::Time();
return file_info.last_modified;
}
@@ -346,6 +348,8 @@ void IndexedDBContextImpl::ForceClose(const GURL origin_url) {
DCHECK_EQ(connections_[origin_url].size(), 0UL);
connections_.erase(origin_url);
}
+ if (factory_)
+ factory_->ForceClose(origin_url);
}
size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) {
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc
index 5daf16d39d..6d7bc1c2d5 100644
--- a/content/browser/indexed_db/indexed_db_cursor.cc
+++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -128,7 +128,7 @@ void IndexedDBCursor::CursorPrefetchIterationOperation(
break;
case indexed_db::CURSOR_KEY_AND_VALUE: {
std::string value;
- value.swap(*cursor_->Value());
+ value.swap(*cursor_->value());
size_estimate += value.size();
found_values.push_back(value);
break;
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h
index 5fd86f44b1..f1afc186a7 100644
--- a/content/browser/indexed_db/indexed_db_cursor.h
+++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -38,7 +38,7 @@ class CONTENT_EXPORT IndexedDBCursor
const IndexedDBKey& primary_key() const { return cursor_->primary_key(); }
std::string* Value() const {
return (cursor_type_ == indexed_db::CURSOR_KEY_ONLY) ? NULL
- : cursor_->Value();
+ : cursor_->value();
}
void Close();
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 8d63293268..11ef4be8ed 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -108,7 +108,7 @@ class IndexedDBDatabase::PendingDeleteCall {
};
scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create(
- const string16& name,
+ const base::string16& name,
IndexedDBBackingStore* backing_store,
IndexedDBFactory* factory,
const Identifier& unique_identifier) {
@@ -128,7 +128,7 @@ bool Contains(const T& container, const U& item) {
}
}
-IndexedDBDatabase::IndexedDBDatabase(const string16& name,
+IndexedDBDatabase::IndexedDBDatabase(const base::string16& name,
IndexedDBBackingStore* backing_store,
IndexedDBFactory* factory,
const Identifier& unique_identifier)
@@ -273,7 +273,7 @@ bool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId(
void IndexedDBDatabase::CreateObjectStore(int64 transaction_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment) {
IDB_TRACE("IndexedDBDatabase::CreateObjectStore");
@@ -351,7 +351,7 @@ void IndexedDBDatabase::DeleteObjectStore(int64 transaction_id,
void IndexedDBDatabase::CreateIndex(int64 transaction_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool unique,
bool multi_entry) {
@@ -392,8 +392,9 @@ void IndexedDBDatabase::CreateIndexOperation(
index_metadata.key_path,
index_metadata.unique,
index_metadata.multi_entry)) {
- string16 error_string = ASCIIToUTF16("Internal error creating index '") +
- index_metadata.name + ASCIIToUTF16("'.");
+ base::string16 error_string =
+ ASCIIToUTF16("Internal error creating index '") +
+ index_metadata.name + ASCIIToUTF16("'.");
transaction->Abort(IndexedDBDatabaseError(
blink::WebIDBDatabaseExceptionUnknownError, error_string));
return;
@@ -446,8 +447,9 @@ void IndexedDBDatabase::DeleteIndexOperation(
object_store_id,
index_metadata.id);
if (!ok) {
- string16 error_string = ASCIIToUTF16("Internal error deleting index '") +
- index_metadata.name + ASCIIToUTF16("'.");
+ base::string16 error_string =
+ ASCIIToUTF16("Internal error deleting index '") +
+ index_metadata.name + ASCIIToUTF16("'.");
transaction->Abort(IndexedDBDatabaseError(
blink::WebIDBDatabaseExceptionUnknownError, error_string));
}
@@ -791,7 +793,7 @@ void IndexedDBDatabase::PutOperation(scoped_ptr<PutOperationParams> params,
}
ScopedVector<IndexWriter> index_writers;
- string16 error_message;
+ base::string16 error_message;
bool obeys_constraints = false;
bool backing_store_success = MakeIndexWriters(transaction,
backing_store_.get(),
@@ -897,7 +899,7 @@ void IndexedDBDatabase::SetIndexKeys(int64 transaction_id,
}
ScopedVector<IndexWriter> index_writers;
- string16 error_message;
+ base::string16 error_message;
bool obeys_constraints = false;
DCHECK(metadata_.object_stores.find(object_store_id) !=
metadata_.object_stores.end());
@@ -1219,7 +1221,7 @@ void IndexedDBDatabase::DeleteObjectStoreOperation(
transaction->database()->id(),
object_store_metadata.id);
if (!ok) {
- string16 error_string =
+ base::string16 error_string =
ASCIIToUTF16("Internal error deleting object store '") +
object_store_metadata.name + ASCIIToUTF16("'.");
transaction->Abort(IndexedDBDatabaseError(
@@ -1400,8 +1402,14 @@ void IndexedDBDatabase::CreateTransaction(
connection->callbacks(),
std::set<int64>(object_store_ids.begin(), object_store_ids.end()),
static_cast<indexed_db::TransactionMode>(mode),
- this);
- transactions_[transaction_id] = transaction;
+ this,
+ new IndexedDBBackingStore::Transaction(backing_store_));
+ TransactionCreated(transaction);
+}
+
+void IndexedDBDatabase::TransactionCreated(
+ scoped_refptr<IndexedDBTransaction> transaction) {
+ transactions_[transaction->id()] = transaction;
}
bool IndexedDBDatabase::IsOpenConnectionBlocked() const {
@@ -1449,7 +1457,7 @@ void IndexedDBDatabase::OpenConnection(
DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION,
metadata_.int_version);
} else {
- string16 message;
+ base::string16 message;
if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
message = ASCIIToUTF16(
"Internal error opening database with no version specified.");
@@ -1714,7 +1722,7 @@ void IndexedDBDatabase::DeleteObjectStoreAbortOperation(
}
void IndexedDBDatabase::VersionChangeAbortOperation(
- const string16& previous_version,
+ const base::string16& previous_version,
int64 previous_int_version,
IndexedDBTransaction* transaction) {
IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index fa730b0ebf..6297f3dcd6 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -52,7 +52,7 @@ class CONTENT_EXPORT IndexedDBDatabase
static const int64 kMinimumIndexId = 30;
static scoped_refptr<IndexedDBDatabase> Create(
- const string16& name,
+ const base::string16& name,
IndexedDBBackingStore* backing_store,
IndexedDBFactory* factory,
const Identifier& unique_identifier);
@@ -88,7 +88,7 @@ class CONTENT_EXPORT IndexedDBDatabase
void CreateObjectStore(int64 transaction_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment);
void DeleteObjectStore(int64 transaction_id, int64 object_store_id);
@@ -105,7 +105,7 @@ class CONTENT_EXPORT IndexedDBDatabase
void CreateIndex(int64 transaction_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath& key_path,
bool unique,
bool multi_entry);
@@ -118,6 +118,7 @@ class CONTENT_EXPORT IndexedDBDatabase
return transaction_coordinator_;
}
+ void TransactionCreated(scoped_refptr<IndexedDBTransaction> transaction);
void TransactionStarted(IndexedDBTransaction* transaction);
void TransactionFinished(IndexedDBTransaction* transaction);
void TransactionFinishedAndCompleteFired(IndexedDBTransaction* transaction);
@@ -198,7 +199,7 @@ class CONTENT_EXPORT IndexedDBDatabase
blink::WebIDBDataLoss data_loss,
std::string data_loss_message,
IndexedDBTransaction* transaction);
- void VersionChangeAbortOperation(const string16& previous_version,
+ void VersionChangeAbortOperation(const base::string16& previous_version,
int64 previous_int_version,
IndexedDBTransaction* transaction);
void CreateIndexOperation(int64 object_store_id,
@@ -243,7 +244,7 @@ class CONTENT_EXPORT IndexedDBDatabase
private:
friend class base::RefCounted<IndexedDBDatabase>;
- IndexedDBDatabase(const string16& name,
+ IndexedDBDatabase(const base::string16& name,
IndexedDBBackingStore* backing_store,
IndexedDBFactory* factory,
const Identifier& unique_identifier);
diff --git a/content/browser/indexed_db/indexed_db_database_error.h b/content/browser/indexed_db/indexed_db_database_error.h
index 297bec7be3..1a4f449d81 100644
--- a/content/browser/indexed_db/indexed_db_database_error.h
+++ b/content/browser/indexed_db/indexed_db_database_error.h
@@ -17,16 +17,16 @@ class IndexedDBDatabaseError {
: code_(code) {}
IndexedDBDatabaseError(uint16 code, const char* message)
: code_(code), message_(ASCIIToUTF16(message)) {}
- IndexedDBDatabaseError(uint16 code, const string16& message)
+ IndexedDBDatabaseError(uint16 code, const base::string16& message)
: code_(code), message_(message) {}
~IndexedDBDatabaseError() {}
uint16 code() const { return code_; }
- const string16& message() const { return message_; }
+ const base::string16& message() const { return message_; }
private:
const uint16 code_;
- const string16 message_;
+ const base::string16 message_;
};
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_factory.cc b/content/browser/indexed_db/indexed_db_factory.cc
index 2cfef62c90..d6883e6188 100644
--- a/content/browser/indexed_db/indexed_db_factory.cc
+++ b/content/browser/indexed_db/indexed_db_factory.cc
@@ -90,6 +90,11 @@ bool IndexedDBFactory::HasLastBackingStoreReference(const GURL& origin_url)
return ptr->HasOneRef();
}
+void IndexedDBFactory::ForceClose(const GURL& origin_url) {
+ if (backing_store_map_.find(origin_url) != backing_store_map_.end())
+ ReleaseBackingStore(origin_url, true /* immediate */);
+}
+
void IndexedDBFactory::ContextDestroyed() {
// Timers on backing stores hold a reference to this factory. When the
// context (which nominally owns this factory) is destroyed during thread
@@ -127,10 +132,11 @@ void IndexedDBFactory::GetDatabaseNames(
}
callbacks->OnSuccess(backing_store->GetDatabaseNames());
+ ReleaseBackingStore(origin_url, false /* immediate */);
}
void IndexedDBFactory::DeleteDatabase(
- const string16& name,
+ const base::string16& name,
scoped_refptr<IndexedDBCallbacks> callbacks,
const GURL& origin_url,
const base::FilePath& data_directory) {
@@ -177,6 +183,7 @@ void IndexedDBFactory::DeleteDatabase(
database_map_[unique_identifier] = database;
database->DeleteDatabase(callbacks);
database_map_.erase(unique_identifier);
+ ReleaseBackingStore(origin_url, false /* immediate */);
}
void IndexedDBFactory::HandleBackingStoreFailure(const GURL& origin_url) {
@@ -191,6 +198,15 @@ bool IndexedDBFactory::IsBackingStoreOpenForTesting(const GURL& origin_url)
return backing_store_map_.find(origin_url) != backing_store_map_.end();
}
+bool IndexedDBFactory::IsBackingStorePendingCloseForTesting(
+ const GURL& origin_url) const {
+ IndexedDBBackingStoreMap::const_iterator it =
+ backing_store_map_.find(origin_url);
+ if (it == backing_store_map_.end())
+ return false;
+ return it->second->close_timer()->IsRunning();
+}
+
scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore(
const GURL& origin_url,
const base::FilePath& data_directory,
@@ -233,7 +249,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore(
}
void IndexedDBFactory::Open(
- const string16& name,
+ const base::string16& name,
int64 version,
int64 transaction_id,
scoped_refptr<IndexedDBCallbacks> callbacks,
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h
index b143853a3a..e27ad69442 100644
--- a/content/browser/indexed_db/indexed_db_factory.h
+++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -36,7 +36,7 @@ class CONTENT_EXPORT IndexedDBFactory
void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
const GURL& origin_url,
const base::FilePath& data_directory);
- void Open(const string16& name,
+ void Open(const base::string16& name,
int64 version,
int64 transaction_id,
scoped_refptr<IndexedDBCallbacks> callbacks,
@@ -44,7 +44,7 @@ class CONTENT_EXPORT IndexedDBFactory
const GURL& origin_url,
const base::FilePath& data_directory);
- void DeleteDatabase(const string16& name,
+ void DeleteDatabase(const base::string16& name,
scoped_refptr<IndexedDBCallbacks> callbacks,
const GURL& origin_url,
const base::FilePath& data_directory);
@@ -56,6 +56,11 @@ class CONTENT_EXPORT IndexedDBFactory
const GURL& origin_url) const;
bool IsBackingStoreOpenForTesting(const GURL& origin_url) const;
+ bool IsBackingStorePendingCloseForTesting(const GURL& origin_url) const;
+
+ // Called by IndexedDBContext after all connections are closed, to
+ // ensure the backing store closed immediately.
+ void ForceClose(const GURL& origin_url);
// Called by the IndexedDBContext destructor so the factory can do cleanup.
void ContextDestroyed();
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 859c2b722d..cb007d521c 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -217,7 +217,7 @@ TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
new LookingForQuotaErrorMockCallbacks;
scoped_refptr<IndexedDBDatabaseCallbacks> dummy_database_callbacks =
new IndexedDBDatabaseCallbacks(NULL, 0, 0);
- const string16 name(ASCIIToUTF16("name"));
+ const base::string16 name(ASCIIToUTF16("name"));
factory->Open(name,
1, /* version */
2, /* transaction_id */
@@ -250,8 +250,12 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
EXPECT_TRUE(callbacks->connection());
EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+
callbacks->connection()->ForceClose();
+
EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
}
TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
@@ -283,6 +287,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
callbacks->connection()->Close();
EXPECT_TRUE(store->HasOneRef()); // Factory.
EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingCloseForTesting(origin));
EXPECT_TRUE(store->close_timer()->IsRunning());
// Take a ref so it won't be destroyed out from under the test.
@@ -292,6 +297,98 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
EXPECT_TRUE(store->HasOneRef()); // Local.
EXPECT_FALSE(store->close_timer()->IsRunning());
EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+}
+
+TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) {
+ GURL origin("http://localhost:81");
+
+ base::ScopedTempDir temp_directory;
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+
+ scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL);
+ EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+
+ const bool expect_connection = false;
+ scoped_refptr<MockIndexedDBCallbacks> callbacks(
+ new MockIndexedDBCallbacks(expect_connection));
+ factory->DeleteDatabase(ASCIIToUTF16("db"),
+ callbacks,
+ origin,
+ temp_directory.path());
+
+ EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+
+ // Now simulate shutdown, which should stop the timer.
+ factory->ContextDestroyed();
+
+ EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+}
+
+TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) {
+ GURL origin("http://localhost:81");
+
+ base::ScopedTempDir temp_directory;
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+
+ scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL);
+ EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+
+ const bool expect_connection = false;
+ scoped_refptr<MockIndexedDBCallbacks> callbacks(
+ new MockIndexedDBCallbacks(expect_connection));
+ factory->GetDatabaseNames(callbacks,
+ origin,
+ temp_directory.path());
+
+ EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+
+ // Now simulate shutdown, which should stop the timer.
+ factory->ContextDestroyed();
+
+ EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+}
+
+TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
+ GURL origin("http://localhost:81");
+
+ base::ScopedTempDir temp_directory;
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+
+ scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL);
+
+ scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
+ scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
+ new MockIndexedDBDatabaseCallbacks());
+ const int64 transaction_id = 1;
+ factory->Open(ASCIIToUTF16("db"),
+ IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION,
+ transaction_id,
+ callbacks,
+ db_callbacks,
+ origin,
+ temp_directory.path());
+
+ EXPECT_TRUE(callbacks->connection());
+ EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+
+ callbacks->connection()->Close();
+
+ EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingCloseForTesting(origin));
+
+ factory->ForceClose(origin);
+
+ EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingCloseForTesting(origin));
+
+ // Ensure it is safe if the store is not open.
+ factory->ForceClose(origin);
}
} // namespace
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
index 8766162604..3efd410727 100644
--- a/content/browser/indexed_db/indexed_db_fake_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -10,19 +10,19 @@ namespace content {
IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() {}
-std::vector<string16> IndexedDBFakeBackingStore::GetDatabaseNames() {
- return std::vector<string16>();
+std::vector<base::string16> IndexedDBFakeBackingStore::GetDatabaseNames() {
+ return std::vector<base::string16>();
}
bool IndexedDBFakeBackingStore::GetIDBDatabaseMetaData(
- const string16& name,
+ const base::string16& name,
IndexedDBDatabaseMetadata*,
bool* found) {
return true;
}
bool IndexedDBFakeBackingStore::CreateIDBDatabaseMetaData(
- const string16& name,
- const string16& version,
+ const base::string16& name,
+ const base::string16& version,
int64 int_version,
int64* row_id) {
return true;
@@ -32,14 +32,14 @@ bool IndexedDBFakeBackingStore::UpdateIDBDatabaseIntVersion(Transaction*,
int64 version) {
return false;
}
-bool IndexedDBFakeBackingStore::DeleteDatabase(const string16& name) {
+bool IndexedDBFakeBackingStore::DeleteDatabase(const base::string16& name) {
return true;
}
bool IndexedDBFakeBackingStore::CreateObjectStore(Transaction*,
int64 database_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath&,
bool auto_increment) {
return false;
@@ -85,7 +85,7 @@ bool IndexedDBFakeBackingStore::CreateIndex(Transaction*,
int64 database_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath&,
bool is_unique,
bool is_multi_entry) {
@@ -146,4 +146,10 @@ IndexedDBFakeBackingStore::OpenIndexCursor(
return scoped_ptr<IndexedDBBackingStore::Cursor>();
}
+IndexedDBFakeBackingStore::FakeTransaction::FakeTransaction(bool result)
+ : IndexedDBBackingStore::Transaction(NULL), result_(result) {}
+void IndexedDBFakeBackingStore::FakeTransaction::Begin() {}
+bool IndexedDBFakeBackingStore::FakeTransaction::Commit() { return result_; }
+void IndexedDBFakeBackingStore::FakeTransaction::Rollback() {}
+
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.h b/content/browser/indexed_db/indexed_db_fake_backing_store.h
index 07b63de648..14b956244d 100644
--- a/content/browser/indexed_db/indexed_db_fake_backing_store.h
+++ b/content/browser/indexed_db/indexed_db_fake_backing_store.h
@@ -17,23 +17,23 @@ class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
: IndexedDBBackingStore(GURL("http://localhost:81"),
scoped_ptr<LevelDBDatabase>(),
scoped_ptr<LevelDBComparator>()) {}
- virtual std::vector<string16> GetDatabaseNames() OVERRIDE;
- virtual bool GetIDBDatabaseMetaData(const string16& name,
+ virtual std::vector<base::string16> GetDatabaseNames() OVERRIDE;
+ virtual bool GetIDBDatabaseMetaData(const base::string16& name,
IndexedDBDatabaseMetadata*,
bool* found) OVERRIDE;
- virtual bool CreateIDBDatabaseMetaData(const string16& name,
- const string16& version,
+ virtual bool CreateIDBDatabaseMetaData(const base::string16& name,
+ const base::string16& version,
int64 int_version,
int64* row_id) OVERRIDE;
virtual bool UpdateIDBDatabaseIntVersion(Transaction*,
int64 row_id,
int64 version) OVERRIDE;
- virtual bool DeleteDatabase(const string16& name) OVERRIDE;
+ virtual bool DeleteDatabase(const base::string16& name) OVERRIDE;
virtual bool CreateObjectStore(Transaction*,
int64 database_id,
int64 object_store_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath&,
bool auto_increment) OVERRIDE;
@@ -65,7 +65,7 @@ class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
int64 database_id,
int64 object_store_id,
int64 index_id,
- const string16& name,
+ const base::string16& name,
const IndexedDBKeyPath&,
bool is_unique,
bool is_multi_entry) OVERRIDE;
@@ -107,6 +107,17 @@ class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
indexed_db::CursorDirection)
OVERRIDE;
+ class FakeTransaction : public IndexedDBBackingStore::Transaction {
+ public:
+ FakeTransaction(bool result);
+ virtual void Begin() OVERRIDE;
+ virtual bool Commit() OVERRIDE;
+ virtual void Rollback() OVERRIDE;
+
+ private:
+ bool result_;
+ };
+
protected:
friend class base::RefCounted<IndexedDBFakeBackingStore>;
virtual ~IndexedDBFakeBackingStore();
diff --git a/content/browser/indexed_db/indexed_db_index_writer.cc b/content/browser/indexed_db/indexed_db_index_writer.cc
index 3b36cad0ec..1c2ac0ab5a 100644
--- a/content/browser/indexed_db/indexed_db_index_writer.cc
+++ b/content/browser/indexed_db/indexed_db_index_writer.cc
@@ -34,7 +34,7 @@ bool IndexWriter::VerifyIndexKeys(
int64 index_id,
bool* can_add_keys,
const IndexedDBKey& primary_key,
- string16* error_message) const {
+ base::string16* error_message) const {
*can_add_keys = false;
for (size_t i = 0; i < index_keys_.size(); ++i) {
bool ok = AddingKeyAllowed(backing_store,
@@ -122,7 +122,7 @@ bool MakeIndexWriters(
const std::vector<int64>& index_ids,
const std::vector<IndexedDBDatabase::IndexKeys>& index_keys,
ScopedVector<IndexWriter>* index_writers,
- string16* error_message,
+ base::string16* error_message,
bool* completed) {
DCHECK_EQ(index_ids.size(), index_keys.size());
*completed = false;
diff --git a/content/browser/indexed_db/indexed_db_index_writer.h b/content/browser/indexed_db/indexed_db_index_writer.h
index 2ea1c98c8e..8a2cdadee3 100644
--- a/content/browser/indexed_db/indexed_db_index_writer.h
+++ b/content/browser/indexed_db/indexed_db_index_writer.h
@@ -34,7 +34,7 @@ class IndexWriter {
int64 index_id,
bool* can_add_keys,
const IndexedDBKey& primary_key,
- string16* error_message) const WARN_UNUSED_RESULT;
+ base::string16* error_message) const WARN_UNUSED_RESULT;
void WriteIndexKeys(const IndexedDBBackingStore::RecordIdentifier& record,
IndexedDBBackingStore* store,
@@ -68,7 +68,7 @@ bool MakeIndexWriters(
const std::vector<int64>& index_ids,
const std::vector<IndexedDBDatabase::IndexKeys>& index_keys,
ScopedVector<IndexWriter>* index_writers,
- string16* error_message,
+ base::string16* error_message,
bool* completed) WARN_UNUSED_RESULT;
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/content/browser/indexed_db/indexed_db_leveldb_coding.cc
index dd3964ab44..b6b465f65e 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding.cc
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding.cc
@@ -257,7 +257,7 @@ void EncodeVarInt(int64 value, std::string* into) {
} while (n);
}
-void EncodeString(const string16& value, std::string* into) {
+void EncodeString(const base::string16& value, std::string* into) {
if (value.empty())
return;
// Backing store is UTF-16BE, convert from host endianness.
@@ -277,7 +277,7 @@ void EncodeBinary(const std::string& value, std::string* into) {
DCHECK(into->size() >= value.size());
}
-void EncodeStringWithLength(const string16& value, std::string* into) {
+void EncodeStringWithLength(const base::string16& value, std::string* into) {
EncodeVarInt(value.length(), into);
EncodeString(value, into);
}
@@ -355,7 +355,7 @@ void EncodeIDBKeyPath(const IndexedDBKeyPath& value, std::string* into) {
break;
}
case WebIDBKeyPathTypeArray: {
- const std::vector<string16>& array = value.array();
+ const std::vector<base::string16>& array = value.array();
size_t count = array.size();
EncodeVarInt(count, into);
for (size_t i = 0; i < count; ++i) {
@@ -421,7 +421,7 @@ bool DecodeVarInt(StringPiece* slice, int64* value) {
return true;
}
-bool DecodeString(StringPiece* slice, string16* value) {
+bool DecodeString(StringPiece* slice, base::string16* value) {
if (slice->empty()) {
value->clear();
return true;
@@ -430,7 +430,7 @@ bool DecodeString(StringPiece* slice, string16* value) {
// Backing store is UTF-16BE, convert to host endianness.
DCHECK(!(slice->size() % sizeof(char16)));
size_t length = slice->size() / sizeof(char16);
- string16 decoded;
+ base::string16 decoded;
decoded.reserve(length);
const char16* encoded = reinterpret_cast<const char16*>(slice->begin());
for (unsigned i = 0; i < length; ++i)
@@ -441,7 +441,7 @@ bool DecodeString(StringPiece* slice, string16* value) {
return true;
}
-bool DecodeStringWithLength(StringPiece* slice, string16* value) {
+bool DecodeStringWithLength(StringPiece* slice, base::string16* value) {
if (slice->empty())
return false;
@@ -510,7 +510,7 @@ bool DecodeIDBKey(StringPiece* slice, scoped_ptr<IndexedDBKey>* value) {
return true;
}
case kIndexedDBKeyStringTypeByte: {
- string16 s;
+ base::string16 s;
if (!DecodeStringWithLength(slice, &s))
return false;
*value = make_scoped_ptr(new IndexedDBKey(s));
@@ -551,7 +551,7 @@ bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
// always written as typed.
if (slice->size() < 3 || (*slice)[0] != kIndexedDBKeyPathTypeCodedByte1 ||
(*slice)[1] != kIndexedDBKeyPathTypeCodedByte2) {
- string16 s;
+ base::string16 s;
if (!DecodeString(slice, &s))
return false;
*value = IndexedDBKeyPath(s);
@@ -569,7 +569,7 @@ bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
*value = IndexedDBKeyPath();
return true;
case WebIDBKeyPathTypeString: {
- string16 string;
+ base::string16 string;
if (!DecodeStringWithLength(slice, &string))
return false;
DCHECK(slice->empty());
@@ -577,13 +577,13 @@ bool DecodeIDBKeyPath(StringPiece* slice, IndexedDBKeyPath* value) {
return true;
}
case WebIDBKeyPathTypeArray: {
- std::vector<string16> array;
+ std::vector<base::string16> array;
int64 count;
if (!DecodeVarInt(slice, &count))
return false;
DCHECK_GE(count, 0);
while (count--) {
- string16 string;
+ base::string16 string;
if (!DecodeStringWithLength(slice, &string))
return false;
array.push_back(string);
@@ -825,17 +825,6 @@ int CompareEncodedIDBKeys(StringPiece* slice_a,
return 0;
}
-int CompareEncodedIDBKeys(const std::string& key_a,
- const std::string& key_b,
- bool* ok) {
- DCHECK(!key_a.empty());
- DCHECK(!key_b.empty());
-
- StringPiece slice_a(key_a);
- StringPiece slice_b(key_b);
- return CompareEncodedIDBKeys(&slice_a, &slice_b, ok);
-}
-
namespace {
template <typename KeyType>
@@ -1324,7 +1313,7 @@ bool DatabaseNameKey::Decode(StringPiece* slice, DatabaseNameKey* result) {
}
std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
- const string16& database_name) {
+ const base::string16& database_name) {
std::string ret = KeyPrefix::EncodeEmpty();
ret.push_back(kDatabaseNameTypeByte);
EncodeStringWithLength(base::ASCIIToUTF16(origin_identifier), &ret);
@@ -1334,7 +1323,7 @@ std::string DatabaseNameKey::Encode(const std::string& origin_identifier,
std::string DatabaseNameKey::EncodeMinKeyForOrigin(
const std::string& origin_identifier) {
- return Encode(origin_identifier, string16());
+ return Encode(origin_identifier, base::string16());
}
std::string DatabaseNameKey::EncodeStopKeyForOrigin(
@@ -1604,8 +1593,9 @@ bool ObjectStoreNamesKey::Decode(StringPiece* slice,
return true;
}
-std::string ObjectStoreNamesKey::Encode(int64 database_id,
- const string16& object_store_name) {
+std::string ObjectStoreNamesKey::Encode(
+ int64 database_id,
+ const base::string16& object_store_name) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
ret.push_back(kObjectStoreNamesTypeByte);
@@ -1641,7 +1631,7 @@ bool IndexNamesKey::Decode(StringPiece* slice, IndexNamesKey* result) {
std::string IndexNamesKey::Encode(int64 database_id,
int64 object_store_id,
- const string16& index_name) {
+ const base::string16& index_name) {
KeyPrefix prefix(database_id);
std::string ret = prefix.Encode();
ret.push_back(kIndexNamesKeyTypeByte);
@@ -1692,10 +1682,6 @@ std::string ObjectStoreDataKey::Encode(int64 database_id,
return Encode(database_id, object_store_id, encoded_key);
}
-int ObjectStoreDataKey::Compare(const ObjectStoreDataKey& other, bool* ok) {
- return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
-}
-
scoped_ptr<IndexedDBKey> ObjectStoreDataKey::user_key() const {
scoped_ptr<IndexedDBKey> key;
StringPiece slice(encoded_user_key_);
@@ -1740,10 +1726,6 @@ std::string ExistsEntryKey::Encode(int64 database_id,
return Encode(database_id, object_store_id, encoded_key);
}
-int ExistsEntryKey::Compare(const ExistsEntryKey& other, bool* ok) {
- return CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
-}
-
scoped_ptr<IndexedDBKey> ExistsEntryKey::user_key() const {
scoped_ptr<IndexedDBKey> key;
StringPiece slice(encoded_user_key_);
@@ -1852,25 +1834,6 @@ std::string IndexDataKey::EncodeMaxKey(int64 database_id,
std::numeric_limits<int64>::max());
}
-int IndexDataKey::Compare(const IndexDataKey& other,
- bool only_compare_index_keys,
- bool* ok) {
- DCHECK_GE(database_id_, 0);
- DCHECK_GE(object_store_id_, 0);
- DCHECK_GE(index_id_, 0);
- int result =
- CompareEncodedIDBKeys(encoded_user_key_, other.encoded_user_key_, ok);
- if (!*ok || result)
- return result;
- if (only_compare_index_keys)
- return 0;
- result = CompareEncodedIDBKeys(
- encoded_primary_key_, other.encoded_primary_key_, ok);
- if (!*ok || result)
- return result;
- return CompareInts(sequence_number_, other.sequence_number_);
-}
-
int64 IndexDataKey::DatabaseId() const {
DCHECK_GE(database_id_, 0);
return database_id_;
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.h b/content/browser/indexed_db/indexed_db_leveldb_coding.h
index 8d0c78047a..556b4605af 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding.h
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding.h
@@ -27,8 +27,9 @@ CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into);
CONTENT_EXPORT void EncodeBool(bool value, std::string* into);
CONTENT_EXPORT void EncodeInt(int64 value, std::string* into);
CONTENT_EXPORT void EncodeVarInt(int64 value, std::string* into);
-CONTENT_EXPORT void EncodeString(const string16& value, std::string* into);
-CONTENT_EXPORT void EncodeStringWithLength(const string16& value,
+CONTENT_EXPORT void EncodeString(const base::string16& value,
+ std::string* into);
+CONTENT_EXPORT void EncodeStringWithLength(const base::string16& value,
std::string* into);
CONTENT_EXPORT void EncodeBinary(const std::string& value, std::string* into);
CONTENT_EXPORT void EncodeDouble(double value, std::string* into);
@@ -45,10 +46,10 @@ CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeInt(base::StringPiece* slice,
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeVarInt(base::StringPiece* slice,
int64* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeString(base::StringPiece* slice,
- string16* value);
+ base::string16* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeStringWithLength(
base::StringPiece* slice,
- string16* value);
+ base::string16* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBinary(base::StringPiece* slice,
std::string* value);
CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeDouble(base::StringPiece* slice,
@@ -68,8 +69,8 @@ CONTENT_EXPORT WARN_UNUSED_RESULT bool ExtractEncodedIDBKey(
base::StringPiece* slice,
std::string* result);
-CONTENT_EXPORT int CompareEncodedIDBKeys(const std::string& a,
- const std::string& b,
+CONTENT_EXPORT int CompareEncodedIDBKeys(base::StringPiece* slice1,
+ base::StringPiece* slice2,
bool* ok);
CONTENT_EXPORT int Compare(const base::StringPiece& a,
@@ -188,18 +189,19 @@ class DatabaseNameKey {
public:
static bool Decode(base::StringPiece* slice, DatabaseNameKey* result);
CONTENT_EXPORT static std::string Encode(const std::string& origin_identifier,
- const string16& database_name);
+ const base::string16& database_name);
static std::string EncodeMinKeyForOrigin(
const std::string& origin_identifier);
static std::string EncodeStopKeyForOrigin(
const std::string& origin_identifier);
- string16 origin() const { return origin_; }
- string16 database_name() const { return database_name_; }
+ base::string16 origin() const { return origin_; }
+ base::string16 database_name() const { return database_name_; }
int Compare(const DatabaseNameKey& other);
private:
- string16 origin_; // TODO(jsbell): Store encoded strings, or just pointers.
- string16 database_name_;
+ base::string16 origin_; // TODO(jsbell): Store encoded strings, or just
+ // pointers.
+ base::string16 database_name_;
};
class DatabaseMetaDataKey {
@@ -315,14 +317,15 @@ class ObjectStoreNamesKey {
// because a mapping is kept in the IndexedDBDatabase. Can the
// mapping become unreliable? Can we remove this?
static bool Decode(base::StringPiece* slice, ObjectStoreNamesKey* result);
- CONTENT_EXPORT static std::string Encode(int64 database_id,
- const string16& object_store_name);
+ CONTENT_EXPORT static std::string Encode(
+ int64 database_id,
+ const base::string16& object_store_name);
int Compare(const ObjectStoreNamesKey& other);
- string16 object_store_name() const { return object_store_name_; }
+ base::string16 object_store_name() const { return object_store_name_; }
private:
// TODO(jsbell): Store the encoded string, or just pointers to it.
- string16 object_store_name_;
+ base::string16 object_store_name_;
};
class IndexNamesKey {
@@ -333,13 +336,13 @@ class IndexNamesKey {
static bool Decode(base::StringPiece* slice, IndexNamesKey* result);
CONTENT_EXPORT static std::string Encode(int64 database_id,
int64 object_store_id,
- const string16& index_name);
+ const base::string16& index_name);
int Compare(const IndexNamesKey& other);
- string16 index_name() const { return index_name_; }
+ base::string16 index_name() const { return index_name_; }
private:
int64 object_store_id_;
- string16 index_name_;
+ base::string16 index_name_;
};
class ObjectStoreDataKey {
@@ -351,7 +354,6 @@ class ObjectStoreDataKey {
static std::string Encode(int64 database_id,
int64 object_store_id,
const IndexedDBKey& user_key);
- int Compare(const ObjectStoreDataKey& other, bool* ok);
scoped_ptr<IndexedDBKey> user_key() const;
static const int64 kSpecialIndexNumber;
ObjectStoreDataKey();
@@ -373,7 +375,6 @@ class ExistsEntryKey {
static std::string Encode(int64 database_id,
int64 object_store_id,
const IndexedDBKey& user_key);
- int Compare(const ExistsEntryKey& other, bool* ok);
scoped_ptr<IndexedDBKey> user_key() const;
static const int64 kSpecialIndexNumber;
@@ -410,9 +411,6 @@ class IndexDataKey {
CONTENT_EXPORT static std::string EncodeMaxKey(int64 database_id,
int64 object_store_id,
int64 index_id);
- int Compare(const IndexDataKey& other,
- bool only_compare_index_keys,
- bool* ok);
int64 DatabaseId() const;
int64 ObjectStoreId() const;
int64 IndexId() const;
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
index 6d6ab0bda5..44c4ab88cd 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
@@ -111,8 +111,13 @@ TEST(IndexedDBLevelDBCodingTest, EncodeBool) {
}
static int CompareKeys(const std::string& a, const std::string& b) {
+ DCHECK(!a.empty());
+ DCHECK(!b.empty());
+
+ StringPiece slice_a(a);
+ StringPiece slice_b(b);
bool ok;
- int result = CompareEncodedIDBKeys(a, b, &ok);
+ int result = CompareEncodedIDBKeys(&slice_a, &slice_b, &ok);
EXPECT_TRUE(ok);
return result;
}
@@ -304,7 +309,7 @@ TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) {
}
}
-static std::string WrappedEncodeString(string16 value) {
+static std::string WrappedEncodeString(base::string16 value) {
std::string buffer;
EncodeString(value, &buffer);
return buffer;
@@ -321,24 +326,24 @@ TEST(IndexedDBLevelDBCodingTest, EncodeString) {
EXPECT_EQ(static_cast<size_t>(6),
WrappedEncodeString(ASCIIToUTF16("foo")).size());
EXPECT_EQ(static_cast<size_t>(6),
- WrappedEncodeString(string16(test_string_a)).size());
+ WrappedEncodeString(base::string16(test_string_a)).size());
EXPECT_EQ(static_cast<size_t>(4),
- WrappedEncodeString(string16(test_string_b)).size());
+ WrappedEncodeString(base::string16(test_string_b)).size());
}
TEST(IndexedDBLevelDBCodingTest, DecodeString) {
const char16 test_string_a[] = {'f', 'o', 'o', '\0'};
const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
- std::vector<string16> test_cases;
- test_cases.push_back(string16());
+ std::vector<base::string16> test_cases;
+ test_cases.push_back(base::string16());
test_cases.push_back(ASCIIToUTF16("a"));
test_cases.push_back(ASCIIToUTF16("foo"));
test_cases.push_back(test_string_a);
test_cases.push_back(test_string_b);
for (size_t i = 0; i < test_cases.size(); ++i) {
- const string16& test_case = test_cases[i];
+ const base::string16& test_case = test_cases[i];
std::string v = WrappedEncodeString(test_case);
StringPiece slice;
@@ -346,7 +351,7 @@ TEST(IndexedDBLevelDBCodingTest, DecodeString) {
slice = StringPiece(&*v.begin(), v.size());
}
- string16 result;
+ base::string16 result;
EXPECT_TRUE(DecodeString(&slice, &result));
EXPECT_EQ(test_case, result);
EXPECT_TRUE(slice.empty());
@@ -360,7 +365,7 @@ TEST(IndexedDBLevelDBCodingTest, DecodeString) {
}
}
-static std::string WrappedEncodeStringWithLength(string16 value) {
+static std::string WrappedEncodeStringWithLength(base::string16 value) {
std::string buffer;
EncodeStringWithLength(value, &buffer);
return buffer;
@@ -371,13 +376,15 @@ TEST(IndexedDBLevelDBCodingTest, EncodeStringWithLength) {
const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
EXPECT_EQ(static_cast<size_t>(1),
- WrappedEncodeStringWithLength(string16()).size());
+ WrappedEncodeStringWithLength(base::string16()).size());
EXPECT_EQ(static_cast<size_t>(3),
WrappedEncodeStringWithLength(ASCIIToUTF16("a")).size());
EXPECT_EQ(static_cast<size_t>(7),
- WrappedEncodeStringWithLength(string16(test_string_a)).size());
+ WrappedEncodeStringWithLength(
+ base::string16(test_string_a)).size());
EXPECT_EQ(static_cast<size_t>(5),
- WrappedEncodeStringWithLength(string16(test_string_b)).size());
+ WrappedEncodeStringWithLength(
+ base::string16(test_string_b)).size());
}
TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) {
@@ -390,20 +397,20 @@ TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) {
long_string[i] = i;
long_string[kLongStringLen] = 0;
- std::vector<string16> test_cases;
+ std::vector<base::string16> test_cases;
test_cases.push_back(ASCIIToUTF16(""));
test_cases.push_back(ASCIIToUTF16("a"));
test_cases.push_back(ASCIIToUTF16("foo"));
- test_cases.push_back(string16(test_string_a));
- test_cases.push_back(string16(test_string_b));
- test_cases.push_back(string16(long_string));
+ test_cases.push_back(base::string16(test_string_a));
+ test_cases.push_back(base::string16(test_string_b));
+ test_cases.push_back(base::string16(long_string));
for (size_t i = 0; i < test_cases.size(); ++i) {
- string16 s = test_cases[i];
+ base::string16 s = test_cases[i];
std::string v = WrappedEncodeStringWithLength(s);
ASSERT_GT(v.size(), static_cast<size_t>(0));
StringPiece slice(v);
- string16 res;
+ base::string16 res;
EXPECT_TRUE(DecodeStringWithLength(&slice, &res));
EXPECT_EQ(s, res);
EXPECT_TRUE(slice.empty());
@@ -444,23 +451,23 @@ TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) {
const char16 test_string_e[] = {0xd834, 0xdd1e, '\0'};
const char16 test_string_f[] = {0xfffd, '\0'};
- std::vector<string16> test_cases;
+ std::vector<base::string16> test_cases;
test_cases.push_back(ASCIIToUTF16(""));
test_cases.push_back(ASCIIToUTF16("a"));
test_cases.push_back(ASCIIToUTF16("b"));
test_cases.push_back(ASCIIToUTF16("baaa"));
test_cases.push_back(ASCIIToUTF16("baab"));
test_cases.push_back(ASCIIToUTF16("c"));
- test_cases.push_back(string16(test_string_a));
- test_cases.push_back(string16(test_string_b));
- test_cases.push_back(string16(test_string_c));
- test_cases.push_back(string16(test_string_d));
- test_cases.push_back(string16(test_string_e));
- test_cases.push_back(string16(test_string_f));
+ test_cases.push_back(base::string16(test_string_a));
+ test_cases.push_back(base::string16(test_string_b));
+ test_cases.push_back(base::string16(test_string_c));
+ test_cases.push_back(base::string16(test_string_d));
+ test_cases.push_back(base::string16(test_string_e));
+ test_cases.push_back(base::string16(test_string_f));
for (size_t i = 0; i < test_cases.size() - 1; ++i) {
- string16 a = test_cases[i];
- string16 b = test_cases[i + 1];
+ base::string16 a = test_cases[i];
+ base::string16 b = test_cases[i + 1];
EXPECT_LT(a.compare(b), 0);
EXPECT_GT(b.compare(a), 0);
@@ -630,7 +637,7 @@ TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) {
}
{
- key_paths.push_back(IndexedDBKeyPath(string16()));
+ key_paths.push_back(IndexedDBKeyPath(base::string16()));
char expected[] = {0, 0, // Header
1, // Type is string
0 // Length is 0
@@ -661,8 +668,8 @@ TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) {
}
{
- std::vector<string16> array;
- array.push_back(string16());
+ std::vector<base::string16> array;
+ array.push_back(base::string16());
array.push_back(ASCIIToUTF16("foo"));
array.push_back(ASCIIToUTF16("foo.bar"));
@@ -700,7 +707,7 @@ TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) {
std::vector<std::string> encoded_paths;
{
- key_paths.push_back(IndexedDBKeyPath(string16()));
+ key_paths.push_back(IndexedDBKeyPath(base::string16()));
encoded_paths.push_back(std::string());
}
{
diff --git a/content/browser/indexed_db/indexed_db_metadata.cc b/content/browser/indexed_db/indexed_db_metadata.cc
index 80d31424c5..47b7219f15 100644
--- a/content/browser/indexed_db/indexed_db_metadata.cc
+++ b/content/browser/indexed_db/indexed_db_metadata.cc
@@ -7,7 +7,7 @@
namespace content {
IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata(
- const string16& name,
+ const base::string16& name,
int64 id,
const IndexedDBKeyPath& key_path,
bool auto_increment,
@@ -23,11 +23,12 @@ IndexedDBObjectStoreMetadata::~IndexedDBObjectStoreMetadata() {}
IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata()
: int_version(NO_INT_VERSION) {}
-IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(const string16& name,
- int64 id,
- const string16& version,
- int64 int_version,
- int64 max_object_store_id)
+IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(
+ const base::string16& name,
+ int64 id,
+ const base::string16& version,
+ int64 int_version,
+ int64 max_object_store_id)
: name(name),
id(id),
version(version),
diff --git a/content/browser/indexed_db/indexed_db_metadata.h b/content/browser/indexed_db/indexed_db_metadata.h
index 4e8562d1f6..00970a61ee 100644
--- a/content/browser/indexed_db/indexed_db_metadata.h
+++ b/content/browser/indexed_db/indexed_db_metadata.h
@@ -15,7 +15,7 @@ namespace content {
struct IndexedDBIndexMetadata {
IndexedDBIndexMetadata() {}
- IndexedDBIndexMetadata(const string16& name,
+ IndexedDBIndexMetadata(const base::string16& name,
int64 id,
const IndexedDBKeyPath& key_path,
bool unique,
@@ -25,7 +25,7 @@ struct IndexedDBIndexMetadata {
key_path(key_path),
unique(unique),
multi_entry(multi_entry) {}
- string16 name;
+ base::string16 name;
int64 id;
IndexedDBKeyPath key_path;
bool unique;
@@ -36,13 +36,13 @@ struct IndexedDBIndexMetadata {
struct CONTENT_EXPORT IndexedDBObjectStoreMetadata {
IndexedDBObjectStoreMetadata();
- IndexedDBObjectStoreMetadata(const string16& name,
+ IndexedDBObjectStoreMetadata(const base::string16& name,
int64 id,
const IndexedDBKeyPath& key_path,
bool auto_increment,
int64 max_index_id);
~IndexedDBObjectStoreMetadata();
- string16 name;
+ base::string16 name;
int64 id;
IndexedDBKeyPath key_path;
bool auto_increment;
@@ -64,16 +64,16 @@ struct CONTENT_EXPORT IndexedDBDatabaseMetadata {
typedef std::map<int64, IndexedDBObjectStoreMetadata> ObjectStoreMap;
IndexedDBDatabaseMetadata();
- IndexedDBDatabaseMetadata(const string16& name,
+ IndexedDBDatabaseMetadata(const base::string16& name,
int64 id,
- const string16& version,
+ const base::string16& version,
int64 int_version,
int64 max_object_store_id);
~IndexedDBDatabaseMetadata();
- string16 name;
+ base::string16 name;
int64 id;
- string16 version;
+ base::string16 version;
int64 int_version;
int64 max_object_store_id;
diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index 25f6620916..cd2f146deb 100644
--- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -66,7 +66,7 @@ class IndexedDBQuotaClientTest : public testing::Test {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath indexeddb_dir =
temp_dir_.path().Append(IndexedDBContextImpl::kIndexedDBDirectory);
- ASSERT_TRUE(file_util::CreateDirectory(indexeddb_dir));
+ ASSERT_TRUE(base::CreateDirectory(indexeddb_dir));
idb_context()->set_data_path_for_testing(indexeddb_dir);
}
@@ -141,8 +141,8 @@ class IndexedDBQuotaClientTest : public testing::Test {
void AddFakeIndexedDB(const GURL& origin, int size) {
base::FilePath file_path_origin = idb_context()->GetFilePathForTesting(
webkit_database::GetIdentifierFromOrigin(origin));
- if (!file_util::CreateDirectory(file_path_origin)) {
- LOG(ERROR) << "failed to file_util::CreateDirectory "
+ if (!base::CreateDirectory(file_path_origin)) {
+ LOG(ERROR) << "failed to base::CreateDirectory "
<< file_path_origin.value();
}
file_path_origin = file_path_origin.Append(FILE_PATH_LITERAL("fake_file"));
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc
index 28f8378f54..b56900b26b 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -18,6 +18,8 @@
namespace content {
+const int64 kInactivityTimeoutPeriodSeconds = 60;
+
IndexedDBTransaction::TaskQueue::TaskQueue() {}
IndexedDBTransaction::TaskQueue::~TaskQueue() { clear(); }
@@ -53,7 +55,8 @@ IndexedDBTransaction::IndexedDBTransaction(
scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
const std::set<int64>& object_store_ids,
indexed_db::TransactionMode mode,
- IndexedDBDatabase* database)
+ IndexedDBDatabase* database,
+ IndexedDBBackingStore::Transaction* backing_store_transaction)
: id_(id),
object_store_ids_(object_store_ids),
mode_(mode),
@@ -62,7 +65,7 @@ IndexedDBTransaction::IndexedDBTransaction(
commit_pending_(false),
callbacks_(callbacks),
database_(database),
- transaction_(database->backing_store()),
+ transaction_(backing_store_transaction),
backing_store_transaction_begun_(false),
should_process_queue_(false),
pending_preemptive_events_(0) {
@@ -86,6 +89,7 @@ void IndexedDBTransaction::ScheduleTask(Operation task, Operation abort_task) {
if (state_ == FINISHED)
return;
+ timeout_timer_.Stop();
used_ = true;
task_queue_.push(task);
++diagnostics_.tasks_scheduled;
@@ -98,6 +102,7 @@ void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type,
if (state_ == FINISHED)
return;
+ timeout_timer_.Stop();
used_ = true;
if (type == IndexedDBDatabase::NORMAL_TASK) {
task_queue_.push(task);
@@ -139,11 +144,13 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) {
// alive while executing this method.
scoped_refptr<IndexedDBTransaction> protect(this);
+ timeout_timer_.Stop();
+
state_ = FINISHED;
should_process_queue_ = false;
if (backing_store_transaction_begun_)
- transaction_.Rollback();
+ transaction_->Rollback();
// Run the abort tasks, if any.
while (!abort_task_stack_.empty()) {
@@ -158,7 +165,7 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) {
// release references and allow the backing store itself to be
// released, and order is critical.
CloseOpenCursors();
- transaction_.Reset();
+ transaction_->Reset();
// Transactions must also be marked as completed before the
// front-end is notified, as the transaction completion unblocks
@@ -229,19 +236,21 @@ void IndexedDBTransaction::Commit() {
// alive while executing this method.
scoped_refptr<IndexedDBTransaction> protect(this);
+ timeout_timer_.Stop();
+
// TODO(jsbell): Run abort tasks if commit fails? http://crbug.com/241843
abort_task_stack_.clear();
state_ = FINISHED;
- bool committed = !used_ || transaction_.Commit();
+ bool committed = !used_ || transaction_->Commit();
// Backing store resources (held via cursors) must be released
// before script callbacks are fired, as the script callbacks may
// release references and allow the backing store itself to be
// released, and order is critical.
CloseOpenCursors();
- transaction_.Reset();
+ transaction_->Reset();
// Transactions must also be marked as completed before the
// front-end is notified, as the transaction completion unblocks
@@ -275,7 +284,7 @@ void IndexedDBTransaction::ProcessTaskQueue() {
should_process_queue_ = false;
if (!backing_store_transaction_begun_) {
- transaction_.Begin();
+ transaction_->Begin();
backing_store_transaction_begun_ = true;
}
@@ -302,8 +311,27 @@ void IndexedDBTransaction::ProcessTaskQueue() {
// If there are no pending tasks, we haven't already committed/aborted,
// and the front-end requested a commit, it is now safe to do so.
- if (!HasPendingTasks() && state_ != FINISHED && commit_pending_)
+ if (!HasPendingTasks() && state_ != FINISHED && commit_pending_) {
Commit();
+ return;
+ }
+
+ // The transaction may have been aborted while processing tasks.
+ if (state_ == FINISHED)
+ return;
+
+ // Otherwise, start a timer in case the front-end gets wedged and
+ // never requests further activity.
+ timeout_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromSeconds(kInactivityTimeoutPeriodSeconds),
+ base::Bind(&IndexedDBTransaction::Timeout, this));
+}
+
+void IndexedDBTransaction::Timeout() {
+ Abort(IndexedDBDatabaseError(
+ blink::WebIDBDatabaseExceptionTimeoutError,
+ ASCIIToUTF16("Transaction timed out due to inactivity.")));
}
void IndexedDBTransaction::CloseOpenCursors() {
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h
index 111101fe09..6684856e57 100644
--- a/content/browser/indexed_db/indexed_db_transaction.h
+++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -13,6 +13,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_database.h"
#include "content/browser/indexed_db/indexed_db_database_error.h"
@@ -22,15 +23,18 @@ namespace content {
class IndexedDBCursor;
class IndexedDBDatabaseCallbacks;
-class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
+class CONTENT_EXPORT IndexedDBTransaction
+ : public NON_EXPORTED_BASE(base::RefCounted<IndexedDBTransaction>) {
public:
typedef base::Callback<void(IndexedDBTransaction*)> Operation;
- IndexedDBTransaction(int64 id,
- scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
- const std::set<int64>& object_store_ids,
- indexed_db::TransactionMode,
- IndexedDBDatabase* db);
+ IndexedDBTransaction(
+ int64 id,
+ scoped_refptr<IndexedDBDatabaseCallbacks> callbacks,
+ const std::set<int64>& object_store_ids,
+ indexed_db::TransactionMode,
+ IndexedDBDatabase* db,
+ IndexedDBBackingStore::Transaction* backing_store_transaction);
virtual void Abort();
void Commit();
@@ -55,7 +59,7 @@ class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
DCHECK_GE(pending_preemptive_events_, 0);
}
IndexedDBBackingStore::Transaction* BackingStoreTransaction() {
- return &transaction_;
+ return transaction_.get();
}
int64 id() const { return id_; }
@@ -69,6 +73,7 @@ class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
};
State state() const { return state_; }
+ bool IsTimeoutTimerRunning() const { return timeout_timer_.IsRunning(); }
struct Diagnostics {
base::Time creation_time;
@@ -90,6 +95,7 @@ class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
void ProcessTaskQueue();
void CloseOpenCursors();
+ void Timeout();
const int64 id_;
const std::set<int64> object_store_ids_;
@@ -131,13 +137,19 @@ class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
TaskQueue preemptive_task_queue_;
TaskStack abort_task_stack_;
- IndexedDBBackingStore::Transaction transaction_;
+ scoped_ptr<IndexedDBBackingStore::Transaction> transaction_;
bool backing_store_transaction_begun_;
bool should_process_queue_;
int pending_preemptive_events_;
std::set<IndexedDBCursor*> open_cursors_;
+
+ // This timer is started after requests have been processed. If no subsequent
+ // requests are processed before the timer fires, assume the script is
+ // unresponsive and abort to unblock the transaction queue.
+ base::OneShotTimer<IndexedDBTransaction> timeout_timer_;
+
Diagnostics diagnostics_;
};
diff --git a/content/browser/indexed_db/indexed_db_transaction_unittest.cc b/content/browser/indexed_db/indexed_db_transaction_unittest.cc
new file mode 100644
index 0000000000..3fc7271b05
--- /dev/null
+++ b/content/browser/indexed_db/indexed_db_transaction_unittest.cc
@@ -0,0 +1,82 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/indexed_db/indexed_db_transaction.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/indexed_db/indexed_db_fake_backing_store.h"
+#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+class IndexedDBTransactionTest : public testing::Test {
+ public:
+ IndexedDBTransactionTest() {
+ IndexedDBFactory* factory = NULL;
+ backing_store_ = new IndexedDBFakeBackingStore();
+ db_ = IndexedDBDatabase::Create(ASCIIToUTF16("db"),
+ backing_store_,
+ factory,
+ IndexedDBDatabase::Identifier());
+ }
+
+ void RunPostedTasks() { message_loop_.RunUntilIdle(); }
+ void DummyOperation(IndexedDBTransaction* transaction) {}
+
+ protected:
+ scoped_refptr<IndexedDBFakeBackingStore> backing_store_;
+ scoped_refptr<IndexedDBDatabase> db_;
+
+ private:
+ base::MessageLoop message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTest);
+};
+
+TEST_F(IndexedDBTransactionTest, Timeout) {
+ const int64 id = 0;
+ const std::set<int64> scope;
+ const bool commit_success = true;
+ scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
+ id,
+ new MockIndexedDBDatabaseCallbacks(),
+ scope,
+ indexed_db::TRANSACTION_READ_ONLY,
+ db_,
+ new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
+ db_->TransactionCreated(transaction);
+
+ // No conflicting transactions, so coordinator will start it immediately:
+ EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
+ EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
+
+ // Schedule a task - timer won't be started until it's processed.
+ transaction->ScheduleTask(base::Bind(
+ &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
+ EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
+
+ RunPostedTasks();
+ EXPECT_TRUE(transaction->IsTimeoutTimerRunning());
+
+ // Abort should cancel the timer.
+ transaction->Abort();
+ EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
+ EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
+
+ // This task will be ignored.
+ transaction->ScheduleTask(base::Bind(
+ &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
+ EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
+ EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
+}
+
+} // namespace
+
+} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
index 43613af566..b94b20d431 100644
--- a/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -69,8 +69,8 @@ TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) {
webkit_database::GetIdentifierFromOrigin(kNormalOrigin));
session_only_path = idb_context->GetFilePathForTesting(
webkit_database::GetIdentifierFromOrigin(kSessionOnlyOrigin));
- ASSERT_TRUE(file_util::CreateDirectory(normal_path));
- ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
+ ASSERT_TRUE(base::CreateDirectory(normal_path));
+ ASSERT_TRUE(base::CreateDirectory(session_only_path));
FlushIndexedDBTaskRunner();
message_loop_.RunUntilIdle();
}
@@ -103,8 +103,8 @@ TEST_F(IndexedDBTest, SetForceKeepSessionState) {
webkit_database::GetIdentifierFromOrigin(kNormalOrigin));
session_only_path = idb_context->GetFilePathForTesting(
webkit_database::GetIdentifierFromOrigin(kSessionOnlyOrigin));
- ASSERT_TRUE(file_util::CreateDirectory(normal_path));
- ASSERT_TRUE(file_util::CreateDirectory(session_only_path));
+ ASSERT_TRUE(base::CreateDirectory(normal_path));
+ ASSERT_TRUE(base::CreateDirectory(session_only_path));
message_loop_.RunUntilIdle();
}
@@ -158,7 +158,7 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
test_path = idb_context->GetFilePathForTesting(
webkit_database::GetIdentifierFromOrigin(kTestOrigin));
- ASSERT_TRUE(file_util::CreateDirectory(test_path));
+ ASSERT_TRUE(base::CreateDirectory(test_path));
const bool kExpectForceClose = true;
@@ -208,7 +208,7 @@ TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) {
base::FilePath test_path = idb_context->GetFilePathForTesting(
webkit_database::GetIdentifierFromOrigin(kTestOrigin));
- ASSERT_TRUE(file_util::CreateDirectory(test_path));
+ ASSERT_TRUE(base::CreateDirectory(test_path));
scoped_ptr<LevelDBLock> lock =
LevelDBDatabase::LockForTesting(test_path);
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.cc b/content/browser/indexed_db/mock_indexed_db_callbacks.cc
index c5f93e00ef..a585246ab3 100644
--- a/content/browser/indexed_db/mock_indexed_db_callbacks.cc
+++ b/content/browser/indexed_db/mock_indexed_db_callbacks.cc
@@ -9,9 +9,17 @@
namespace content {
MockIndexedDBCallbacks::MockIndexedDBCallbacks()
- : IndexedDBCallbacks(NULL, 0, 0) {}
+ : IndexedDBCallbacks(NULL, 0, 0), expect_connection_(true) {}
+MockIndexedDBCallbacks::MockIndexedDBCallbacks(bool expect_connection)
+ : IndexedDBCallbacks(NULL, 0, 0), expect_connection_(expect_connection) {}
-MockIndexedDBCallbacks::~MockIndexedDBCallbacks() { EXPECT_TRUE(connection_); }
+MockIndexedDBCallbacks::~MockIndexedDBCallbacks() {
+ EXPECT_EQ(expect_connection_, !!connection_);
+}
+
+void MockIndexedDBCallbacks::OnSuccess() {}
+
+void MockIndexedDBCallbacks::OnSuccess(const std::vector<base::string16>&) {}
void MockIndexedDBCallbacks::OnSuccess(
scoped_ptr<IndexedDBConnection> connection,
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.h b/content/browser/indexed_db/mock_indexed_db_callbacks.h
index 3d6b949bd2..d4d9217c7d 100644
--- a/content/browser/indexed_db/mock_indexed_db_callbacks.h
+++ b/content/browser/indexed_db/mock_indexed_db_callbacks.h
@@ -13,7 +13,10 @@ namespace content {
class MockIndexedDBCallbacks : public IndexedDBCallbacks {
public:
MockIndexedDBCallbacks();
+ MockIndexedDBCallbacks(bool expect_connection);
+ virtual void OnSuccess() OVERRIDE;
+ virtual void OnSuccess(const std::vector<base::string16>&) OVERRIDE;
virtual void OnSuccess(scoped_ptr<IndexedDBConnection> connection,
const IndexedDBDatabaseMetadata& metadata) OVERRIDE;
@@ -22,6 +25,7 @@ class MockIndexedDBCallbacks : public IndexedDBCallbacks {
private:
virtual ~MockIndexedDBCallbacks();
scoped_ptr<IndexedDBConnection> connection_;
+ bool expect_connection_;
DISALLOW_COPY_AND_ASSIGN(MockIndexedDBCallbacks);
};
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc
index 5983052246..93d7e839aa 100644
--- a/content/browser/loader/async_resource_handler.cc
+++ b/content/browser/loader/async_resource_handler.cc
@@ -151,6 +151,7 @@ bool AsyncResourceHandler::OnRequestRedirected(int request_id,
return false;
*defer = did_defer_ = true;
+ OnDefer();
if (rdh_->delegate()) {
rdh_->delegate()->OnRequestRedirected(
@@ -287,6 +288,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int bytes_read,
"Net.AsyncResourceHandler_PendingDataCount_WhenFull",
pending_data_count_, 0, 100, 100);
*defer = did_defer_ = true;
+ OnDefer();
}
return true;
@@ -377,8 +379,13 @@ bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() {
void AsyncResourceHandler::ResumeIfDeferred() {
if (did_defer_) {
did_defer_ = false;
+ request()->LogUnblocked();
controller()->Resume();
}
}
+void AsyncResourceHandler::OnDefer() {
+ request()->LogBlockedBy("AsyncResourceHandler");
+}
+
} // namespace content
diff --git a/content/browser/loader/async_resource_handler.h b/content/browser/loader/async_resource_handler.h
index ac15b5963a..f603f4f858 100644
--- a/content/browser/loader/async_resource_handler.h
+++ b/content/browser/loader/async_resource_handler.h
@@ -72,6 +72,7 @@ class AsyncResourceHandler : public ResourceHandler,
bool EnsureResourceBufferIsInitialized();
void ResumeIfDeferred();
+ void OnDefer();
scoped_refptr<ResourceBuffer> buffer_;
ResourceDispatcherHostImpl* rdh_;
diff --git a/content/browser/loader/buffered_resource_handler.cc b/content/browser/loader/buffered_resource_handler.cc
index bc63665140..2a5ef9cd12 100644
--- a/content/browser/loader/buffered_resource_handler.cc
+++ b/content/browser/loader/buffered_resource_handler.cc
@@ -444,7 +444,7 @@ bool BufferedResourceHandler::HasSupportingPlugin(bool* stale) {
bool allow_wildcard = false;
WebPluginInfo plugin;
return PluginServiceImpl::GetInstance()->GetPluginInfo(
- info->GetChildID(), info->GetRouteID(), info->GetContext(),
+ info->GetChildID(), info->GetRenderFrameID(), info->GetContext(),
request()->url(), GURL(), response_->head.mime_type, allow_wildcard,
stale, &plugin, NULL);
#else
diff --git a/content/browser/loader/power_save_block_resource_throttle.cc b/content/browser/loader/power_save_block_resource_throttle.cc
index d9b843cba2..7a084b0a71 100644
--- a/content/browser/loader/power_save_block_resource_throttle.cc
+++ b/content/browser/loader/power_save_block_resource_throttle.cc
@@ -34,6 +34,10 @@ void PowerSaveBlockResourceThrottle::WillProcessResponse(bool* defer) {
timer_.Stop();
}
+const char* PowerSaveBlockResourceThrottle::GetNameForLogging() const {
+ return "PowerSaveBlockResourceThrottle";
+}
+
void PowerSaveBlockResourceThrottle::ActivatePowerSaveBlocker() {
power_save_blocker_ = PowerSaveBlocker::Create(
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
diff --git a/content/browser/loader/power_save_block_resource_throttle.h b/content/browser/loader/power_save_block_resource_throttle.h
index e94b542615..2a4f9b39c5 100644
--- a/content/browser/loader/power_save_block_resource_throttle.h
+++ b/content/browser/loader/power_save_block_resource_throttle.h
@@ -24,6 +24,7 @@ class PowerSaveBlockResourceThrottle : public ResourceThrottle {
// ResourceThrottle overrides:
virtual void WillStartRequest(bool* defer) OVERRIDE;
virtual void WillProcessResponse(bool* defer) OVERRIDE;
+ virtual const char* GetNameForLogging() const OVERRIDE;
private:
void ActivatePowerSaveBlocker();
diff --git a/content/browser/loader/resource_dispatcher_host_browsertest.cc b/content/browser/loader/resource_dispatcher_host_browsertest.cc
index 0a763fede6..011c9758fa 100644
--- a/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -59,13 +59,13 @@ class ResourceDispatcherHostBrowserTest : public ContentBrowserTest,
void CheckTitleTest(const GURL& url,
const std::string& expected_title) {
- string16 expected_title16(ASCIIToUTF16(expected_title));
+ base::string16 expected_title16(ASCIIToUTF16(expected_title));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
NavigateToURL(shell(), url);
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
- bool GetPopupTitle(const GURL& url, string16* title) {
+ bool GetPopupTitle(const GURL& url, base::string16* title) {
NavigateToURL(shell(), url);
ShellAddedObserver new_shell_observer;
@@ -96,7 +96,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) {
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
GURL url(embedded_test_server()->GetURL("/dynamic1.html"));
- string16 title;
+ base::string16 title;
ASSERT_TRUE(GetPopupTitle(url, &title));
EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Popup Title"), true))
<< "Actual title: " << title;
@@ -108,7 +108,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle2) {
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
GURL url(embedded_test_server()->GetURL("/dynamic2.html"));
- string16 title;
+ base::string16 title;
ASSERT_TRUE(GetPopupTitle(url, &title));
EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Dynamic Title"), true))
<< "Actual title: " << title;
@@ -364,7 +364,7 @@ IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
// URLs are prohibited by policy from interacting with sensitive chrome
// pages of which the error page is one. Instead, use automation to kick
// off the navigation, and wait to see that the tab loads.
- string16 expected_title16(ASCIIToUTF16("Title Of Awesomeness"));
+ base::string16 expected_title16(ASCIIToUTF16("Title Of Awesomeness"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
bool success;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 84cfb57fce..831a368e16 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1100,6 +1100,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
route_id,
request_data.origin_pid,
request_id,
+ request_data.render_frame_id,
request_data.is_main_frame,
request_data.frame_id,
request_data.parent_is_main_frame,
@@ -1131,6 +1132,23 @@ void ResourceDispatcherHostImpl::BeginRequest(
request, filter_->appcache_service(), child_id,
request_data.appcache_host_id, request_data.resource_type);
+ scoped_ptr<ResourceHandler> handler(
+ CreateResourceHandler(
+ request,
+ request_data, sync_result, route_id, process_type, child_id,
+ resource_context));
+
+ BeginRequestInternal(new_request.Pass(), handler.Pass());
+}
+
+scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
+ net::URLRequest* request,
+ const ResourceHostMsg_Request& request_data,
+ IPC::Message* sync_result,
+ int route_id,
+ int process_type,
+ int child_id,
+ ResourceContext* resource_context) {
// Construct the IPC resource handler.
scoped_ptr<ResourceHandler> handler;
if (sync_result) {
@@ -1185,7 +1203,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
handler.reset(
new ThrottlingResourceHandler(handler.Pass(), request, throttles.Pass()));
- BeginRequestInternal(new_request.Pass(), handler.Pass());
+ return handler.Pass();
}
void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
@@ -1254,6 +1272,7 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
route_id,
0,
request_id_,
+ MSG_ROUTING_NONE, // render_frame_id
false, // is_main_frame
-1, // frame_id
false, // parent_is_main_frame
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index ef0e4cfdb7..2e0253ae51 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -372,6 +372,18 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const ResourceHostMsg_Request& request_data,
IPC::Message* sync_result, // only valid for sync
int route_id); // only valid for async
+
+ // Creates a ResourceHandler to be used by BeginRequest() for normal resource
+ // loading.
+ scoped_ptr<ResourceHandler> CreateResourceHandler(
+ net::URLRequest* request,
+ const ResourceHostMsg_Request& request_data,
+ IPC::Message* sync_result,
+ int route_id,
+ int process_type,
+ int child_id,
+ ResourceContext* resource_context);
+
void OnDataDownloadedACK(int request_id);
void OnUploadProgressACK(int request_id);
void OnCancelRequest(int request_id);
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 895951bba1..52d3432884 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -441,6 +441,10 @@ class GenericResourceThrottle : public ResourceThrottle {
}
}
+ virtual const char* GetNameForLogging() const OVERRIDE {
+ return "GenericResourceThrottle";
+ }
+
void Resume() {
ASSERT_TRUE(this == active_throttle_);
active_throttle_ = NULL;
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 01f95a1756..bdc9644b1d 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -19,6 +19,7 @@
#include "content/public/browser/cert_store.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
+#include "content/public/browser/signed_certificate_timestamp_store.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
@@ -473,6 +474,21 @@ void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) {
}
}
+void ResourceLoader::StoreSignedCertificateTimestamps(
+ const net::SignedCertificateTimestampAndStatusList& sct_list,
+ int process_id,
+ SignedCertificateTimestampIDStatusList* sct_ids) {
+ SignedCertificateTimestampStore* sct_store(
+ SignedCertificateTimestampStore::GetInstance());
+
+ for (net::SignedCertificateTimestampAndStatusList::const_iterator iter =
+ sct_list.begin(); iter != sct_list.end(); ++iter) {
+ const int sct_id(sct_store->Store(iter->sct_, process_id));
+ sct_ids->push_back(
+ SignedCertificateTimestampIDAndStatus(sct_id, iter->status_));
+ }
+}
+
void ResourceLoader::CompleteResponseStarted() {
ResourceRequestInfoImpl* info = GetRequestInfo();
@@ -482,11 +498,19 @@ void ResourceLoader::CompleteResponseStarted() {
if (request_->ssl_info().cert.get()) {
int cert_id = CertStore::GetInstance()->StoreCert(
request_->ssl_info().cert.get(), info->GetChildID());
+
+ SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids;
+ StoreSignedCertificateTimestamps(
+ request_->ssl_info().signed_certificate_timestamps,
+ info->GetChildID(),
+ &signed_certificate_timestamp_ids);
+
response->head.security_info = SerializeSecurityInfo(
cert_id,
request_->ssl_info().cert_status,
request_->ssl_info().security_bits,
- request_->ssl_info().connection_status);
+ request_->ssl_info().connection_status,
+ signed_certificate_timestamp_ids);
} else {
// We should not have any SSL state.
DCHECK(!request_->ssl_info().cert_status &&
@@ -590,9 +614,14 @@ void ResourceLoader::ResponseCompleted() {
if (ssl_info.cert.get() != NULL) {
int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert.get(),
info->GetChildID());
+ SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids;
+ StoreSignedCertificateTimestamps(ssl_info.signed_certificate_timestamps,
+ info->GetChildID(),
+ &signed_certificate_timestamp_ids);
+
security_info = SerializeSecurityInfo(
cert_id, ssl_info.cert_status, ssl_info.security_bits,
- ssl_info.connection_status);
+ ssl_info.connection_status, signed_certificate_timestamp_ids);
}
bool defer = false;
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h
index be2c6c5b97..d0b3ae806c 100644
--- a/content/browser/loader/resource_loader.h
+++ b/content/browser/loader/resource_loader.h
@@ -12,6 +12,7 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/common/content_export.h"
#include "content/public/browser/resource_controller.h"
+#include "content/public/common/signed_certificate_timestamp_id_and_status.h"
#include "net/url_request/url_request.h"
namespace content {
@@ -83,6 +84,14 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
void StartRequestInternal();
void CancelRequestInternal(int error, bool from_renderer);
+ // Stores the SignedCertificateTimestamps held in |sct_list| in the
+ // SignedCertificateTimestampStore singleton, associated with |process_id|.
+ // On return, |sct_ids| contains the assigned ID and verification status of
+ // each SignedCertificateTimestamp.
+ void StoreSignedCertificateTimestamps(
+ const net::SignedCertificateTimestampAndStatusList& sct_list,
+ int process_id,
+ SignedCertificateTimestampIDStatusList* sct_ids);
void CompleteResponseStarted();
void StartReading(bool is_continuation);
void ResumeReading();
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 3d9ba3536e..32ba7ac6de 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -37,6 +37,7 @@ void ResourceRequestInfo::AllocateForTesting(
render_view_id, // route_id
0, // origin_pid
0, // request_id
+ MSG_ROUTING_NONE, // render_frame_id
resource_type == ResourceType::MAIN_FRAME, // is_main_frame
0, // frame_id
false, // parent_is_main_frame
@@ -90,6 +91,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
int route_id,
int origin_pid,
int request_id,
+ int render_frame_id,
bool is_main_frame,
int64 frame_id,
bool parent_is_main_frame,
@@ -112,6 +114,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
route_id_(route_id),
origin_pid_(origin_pid),
request_id_(request_id),
+ render_frame_id_(render_frame_id),
is_main_frame_(is_main_frame),
frame_id_(frame_id),
parent_is_main_frame_(parent_is_main_frame),
@@ -154,6 +157,10 @@ int ResourceRequestInfoImpl::GetRequestID() const {
return request_id_;
}
+int ResourceRequestInfoImpl::GetRenderFrameID() const {
+ return render_frame_id_;
+}
+
bool ResourceRequestInfoImpl::IsMainFrame() const {
return is_main_frame_;
}
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index 093c22f81c..2635106c5c 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -45,6 +45,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int route_id,
int origin_pid,
int request_id,
+ int render_frame_id,
bool is_main_frame,
int64 frame_id,
bool parent_is_main_frame,
@@ -68,6 +69,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
virtual int GetRouteID() const OVERRIDE;
virtual int GetOriginPID() const OVERRIDE;
virtual int GetRequestID() const OVERRIDE;
+ virtual int GetRenderFrameID() const OVERRIDE;
virtual bool IsMainFrame() const OVERRIDE;
virtual int64 GetFrameID() const OVERRIDE;
virtual bool ParentIsMainFrame() const OVERRIDE;
@@ -164,6 +166,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int route_id_;
int origin_pid_;
int request_id_;
+ int render_frame_id_;
bool is_main_frame_;
int64 frame_id_;
bool parent_is_main_frame_;
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc
index 9d05476c3b..4ae240e6fe 100644
--- a/content/browser/loader/resource_scheduler.cc
+++ b/content/browser/loader/resource_scheduler.cc
@@ -159,6 +159,10 @@ class ResourceScheduler::ScheduledResourceRequest
deferred_ = *defer = !ready_;
}
+ virtual const char* GetNameForLogging() const OVERRIDE {
+ return "ResourceScheduler";
+ }
+
void DidChangePriority(int request_id, net::RequestPriority new_priority) {
scheduler_->ReprioritizeRequest(this, new_priority);
}
@@ -370,7 +374,10 @@ void ResourceScheduler::LoadAnyStartablePendingRequests(Client* client) {
StartRequest(request, client);
// StartRequest can modify the pending list, so we (re)start evaluation
- // from the currently highest priority request.
+ // from the currently highest priority request. Avoid copying a singular
+ // iterator, which would trigger undefined behavior.
+ if (client->pending_requests.GetNextHighestIterator().is_null())
+ break;
request_iter = client->pending_requests.GetNextHighestIterator();
} else if (query_result == DO_NOT_START_REQUEST_AND_KEEP_SEARCHING) {
++request_iter;
diff --git a/content/browser/loader/resource_scheduler_unittest.cc b/content/browser/loader/resource_scheduler_unittest.cc
index 60722eea88..07dd333703 100644
--- a/content/browser/loader/resource_scheduler_unittest.cc
+++ b/content/browser/loader/resource_scheduler_unittest.cc
@@ -92,6 +92,7 @@ class FakeResourceContext : public ResourceContext {
virtual net::URLRequestContext* GetRequestContext() OVERRIDE { return NULL; }
virtual bool AllowMicAccess(const GURL& origin) OVERRIDE { return false; }
virtual bool AllowCameraAccess(const GURL& origin) OVERRIDE { return false; }
+ virtual std::string GetMediaDeviceIDSalt() OVERRIDE { return std::string(); }
};
class FakeResourceMessageFilter : public ResourceMessageFilter {
@@ -147,6 +148,7 @@ class ResourceSchedulerTest : public testing::Test {
route_id, // route_id
0, // origin_pid
++next_request_id_, // request_id
+ MSG_ROUTING_NONE, // render_frame_id
false, // is_main_frame
0, // frame_id
false, // parent_is_main_frame
diff --git a/content/browser/loader/throttling_resource_handler.cc b/content/browser/loader/throttling_resource_handler.cc
index 23f77da90c..36c595fbf1 100644
--- a/content/browser/loader/throttling_resource_handler.cc
+++ b/content/browser/loader/throttling_resource_handler.cc
@@ -7,6 +7,7 @@
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/resource_response.h"
+#include "net/url_request/url_request.h"
namespace content {
@@ -17,10 +18,14 @@ ThrottlingResourceHandler::ThrottlingResourceHandler(
: LayeredResourceHandler(request, next_handler.Pass()),
deferred_stage_(DEFERRED_NONE),
throttles_(throttles.Pass()),
- index_(0),
+ next_index_(0),
cancelled_by_resource_throttle_(false) {
- for (size_t i = 0; i < throttles_.size(); ++i)
+ for (size_t i = 0; i < throttles_.size(); ++i) {
throttles_[i]->set_controller(this);
+ // Throttles must have a name, as otherwise, bugs where a throttle fails
+ // to resume a request can be very difficult to debug.
+ DCHECK(throttles_[i]->GetNameForLogging());
+ }
}
ThrottlingResourceHandler::~ThrottlingResourceHandler() {
@@ -33,12 +38,14 @@ bool ThrottlingResourceHandler::OnRequestRedirected(int request_id,
DCHECK(!cancelled_by_resource_throttle_);
*defer = false;
- while (index_ < throttles_.size()) {
- throttles_[index_]->WillRedirectRequest(new_url, defer);
- index_++;
+ while (next_index_ < throttles_.size()) {
+ int index = next_index_;
+ throttles_[index]->WillRedirectRequest(new_url, defer);
+ next_index_++;
if (cancelled_by_resource_throttle_)
return false;
if (*defer) {
+ OnRequestDefered(index);
deferred_stage_ = DEFERRED_REDIRECT;
deferred_url_ = new_url;
deferred_response_ = response;
@@ -46,7 +53,7 @@ bool ThrottlingResourceHandler::OnRequestRedirected(int request_id,
}
}
- index_ = 0; // Reset for next time.
+ next_index_ = 0; // Reset for next time.
return next_handler_->OnRequestRedirected(request_id, new_url, response,
defer);
@@ -58,19 +65,21 @@ bool ThrottlingResourceHandler::OnWillStart(int request_id,
DCHECK(!cancelled_by_resource_throttle_);
*defer = false;
- while (index_ < throttles_.size()) {
- throttles_[index_]->WillStartRequest(defer);
- index_++;
+ while (next_index_ < throttles_.size()) {
+ int index = next_index_;
+ throttles_[index]->WillStartRequest(defer);
+ next_index_++;
if (cancelled_by_resource_throttle_)
return false;
if (*defer) {
+ OnRequestDefered(index);
deferred_stage_ = DEFERRED_START;
deferred_url_ = url;
return true; // Do not cancel.
}
}
- index_ = 0; // Reset for next time.
+ next_index_ = 0; // Reset for next time.
return next_handler_->OnWillStart(request_id, url, defer);
}
@@ -80,19 +89,21 @@ bool ThrottlingResourceHandler::OnResponseStarted(int request_id,
bool* defer) {
DCHECK(!cancelled_by_resource_throttle_);
- while (index_ < throttles_.size()) {
- throttles_[index_]->WillProcessResponse(defer);
- index_++;
+ while (next_index_ < throttles_.size()) {
+ int index = next_index_;
+ throttles_[index]->WillProcessResponse(defer);
+ next_index_++;
if (cancelled_by_resource_throttle_)
return false;
if (*defer) {
+ OnRequestDefered(index);
deferred_stage_ = DEFERRED_RESPONSE;
deferred_response_ = response;
return true; // Do not cancel.
}
}
- index_ = 0; // Reset for next time.
+ next_index_ = 0; // Reset for next time.
return next_handler_->OnResponseStarted(request_id, response, defer);
}
@@ -117,6 +128,8 @@ void ThrottlingResourceHandler::Resume() {
DeferredStage last_deferred_stage = deferred_stage_;
deferred_stage_ = DEFERRED_NONE;
+ // Clear information about the throttle that delayed the request.
+ request()->LogUnblocked();
switch (last_deferred_stage) {
case DEFERRED_NONE:
NOTREACHED();
@@ -177,4 +190,8 @@ void ThrottlingResourceHandler::ResumeResponse() {
}
}
+void ThrottlingResourceHandler::OnRequestDefered(int throttle_index) {
+ request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging());
+}
+
} // namespace content
diff --git a/content/browser/loader/throttling_resource_handler.h b/content/browser/loader/throttling_resource_handler.h
index 65117bc93d..9f98921e26 100644
--- a/content/browser/loader/throttling_resource_handler.h
+++ b/content/browser/loader/throttling_resource_handler.h
@@ -40,7 +40,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
virtual bool OnWillStart(int request_id, const GURL& url,
bool* defer) OVERRIDE;
- // ResourceThrottleController implementation:
+ // ResourceController implementation:
virtual void Cancel() OVERRIDE;
virtual void CancelAndIgnore() OVERRIDE;
virtual void CancelWithError(int error_code) OVERRIDE;
@@ -51,6 +51,10 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
void ResumeRedirect();
void ResumeResponse();
+ // Called when the throttle at |throttle_index| defers a request. Logs the
+ // name of the throttle that delayed the request.
+ void OnRequestDefered(int throttle_index);
+
enum DeferredStage {
DEFERRED_NONE,
DEFERRED_START,
@@ -60,7 +64,7 @@ class ThrottlingResourceHandler : public LayeredResourceHandler,
DeferredStage deferred_stage_;
ScopedVector<ResourceThrottle> throttles_;
- size_t index_;
+ size_t next_index_;
GURL deferred_url_;
scoped_refptr<ResourceResponse> deferred_response_;
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc
index e8d185f579..99b785f235 100644
--- a/content/browser/media/android/browser_media_player_manager.cc
+++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -34,6 +34,14 @@ using media::MediaSourcePlayer;
// attempting to release inactive media players.
static const int kMediaPlayerThreshold = 1;
+// Maximum sizes for various EME message parameters. These are checks to
+// prevent unnecessarily large messages from being passed around, and the sizes
+// are somewhat arbitrary as the EME specification doesn't specify any limits.
+static const size_t kEmeUuidSize = 16;
+static const size_t kEmeTypeMaximum = 50; // Type is a MIME type.
+static const size_t kEmeInitDataMaximum = 10240; // 10 KB
+static const size_t kEmeResponseMaximum = 10240; // 10 KB
+
namespace content {
static BrowserMediaPlayerManager::Factory g_factory = NULL;
@@ -123,11 +131,9 @@ bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
DestroyAllMediaPlayers)
IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM,
OnInitializeCDM)
- IPC_MESSAGE_HANDLER(MediaKeysHostMsg_GenerateKeyRequest,
- OnGenerateKeyRequest)
- IPC_MESSAGE_HANDLER(MediaKeysHostMsg_AddKey, OnAddKey)
- IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CancelKeyRequest,
- OnCancelKeyRequest)
+ IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CreateSession, OnCreateSession)
+ IPC_MESSAGE_HANDLER(MediaKeysHostMsg_UpdateSession, OnUpdateSession)
+ IPC_MESSAGE_HANDLER(MediaKeysHostMsg_ReleaseSession, OnReleaseSession)
#if defined(GOOGLE_TV)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface,
OnNotifyExternalSurface)
@@ -193,11 +199,13 @@ void BrowserMediaPlayerManager::OnTimeUpdate(int player_id,
void BrowserMediaPlayerManager::SetVideoSurface(
gfx::ScopedJavaSurface surface) {
MediaPlayerAndroid* player = GetFullscreenPlayer();
- if (player) {
- player->SetVideoSurface(surface.Pass());
- Send(new MediaPlayerMsg_DidEnterFullscreen(
- routing_id(), player->player_id()));
+ if (!player)
+ return;
+ if (!surface.IsEmpty()) {
+ Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(),
+ player->player_id()));
}
+ player->SetVideoSurface(surface.Pass());
}
void BrowserMediaPlayerManager::OnMediaMetadataChanged(
@@ -355,7 +363,7 @@ void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) {
// During the process, DisableFullscreenEncryptedMediaPlayback() may get
// called before or after OnEnterFullscreen(). If it is called before
// OnEnterFullscreen(), the player will not enter fullscreen. And it will
- // retry the process once the GenerateKeyRequest is allowed to proceed
+ // retry the process once CreateSession() is allowed to proceed.
// TODO(qinmin): make this flag default on android.
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGestureRequirementForMediaFullscreen)) {
@@ -363,34 +371,42 @@ void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) {
}
}
-void BrowserMediaPlayerManager::OnKeyAdded(int media_keys_id,
- uint32 reference_id) {
- Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, reference_id));
-}
+// The following 5 functions are EME MediaKeySession events.
-void BrowserMediaPlayerManager::OnKeyError(
+void BrowserMediaPlayerManager::OnSessionCreated(
int media_keys_id,
- uint32 reference_id,
- media::MediaKeys::KeyError error_code,
- int system_code) {
- Send(new MediaKeysMsg_KeyError(routing_id(), media_keys_id,
- reference_id, error_code, system_code));
+ uint32 session_id,
+ const std::string& web_session_id) {
+ Send(new MediaKeysMsg_SessionCreated(
+ routing_id(), media_keys_id, session_id, web_session_id));
}
-void BrowserMediaPlayerManager::OnKeyMessage(
+void BrowserMediaPlayerManager::OnSessionMessage(
int media_keys_id,
- uint32 reference_id,
+ uint32 session_id,
const std::vector<uint8>& message,
const std::string& destination_url) {
- Send(new MediaKeysMsg_KeyMessage(routing_id(), media_keys_id,
- reference_id, message, destination_url));
+ Send(new MediaKeysMsg_SessionMessage(
+ routing_id(), media_keys_id, session_id, message, destination_url));
}
-void BrowserMediaPlayerManager::OnSetSessionId(int media_keys_id,
- uint32 reference_id,
- const std::string& session_id) {
- Send(new MediaKeysMsg_SetSessionId(
- routing_id(), media_keys_id, reference_id, session_id));
+void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id,
+ uint32 session_id) {
+ Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id));
+}
+
+void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id,
+ uint32 session_id) {
+ Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id));
+}
+
+void BrowserMediaPlayerManager::OnSessionError(
+ int media_keys_id,
+ uint32 session_id,
+ media::MediaKeys::KeyError error_code,
+ int system_code) {
+ Send(new MediaKeysMsg_SessionError(
+ routing_id(), media_keys_id, session_id, error_code, system_code));
}
#if defined(GOOGLE_TV)
@@ -538,27 +554,46 @@ void BrowserMediaPlayerManager::OnInitializeCDM(
int media_keys_id,
const std::vector<uint8>& uuid,
const GURL& frame_url) {
+ if (uuid.size() != kEmeUuidSize) {
+ // This failure will be discovered and reported by OnCreateSession()
+ // as GetDrmBridge() will return null.
+ NOTREACHED() << "Invalid UUID for ID: " << media_keys_id;
+ return;
+ }
+
AddDrmBridge(media_keys_id, uuid, frame_url);
// In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
// is the same as the |player_id|.
OnSetMediaKeys(media_keys_id, media_keys_id);
}
-void BrowserMediaPlayerManager::OnGenerateKeyRequest(
+void BrowserMediaPlayerManager::OnCreateSession(
int media_keys_id,
- uint32 reference_id,
+ uint32 session_id,
const std::string& type,
const std::vector<uint8>& init_data) {
+ if (type.length() > kEmeTypeMaximum) {
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
+ return;
+ }
+ if (init_data.size() > kEmeInitDataMaximum) {
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
+ return;
+ }
+
if (CommandLine::ForCurrentProcess()
->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
- GenerateKeyIfAllowed(media_keys_id, reference_id, type, init_data, true);
+ GenerateKeyIfAllowed(media_keys_id, session_id, type, init_data, true);
return;
}
MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
if (!drm_bridge) {
DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
- OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0);
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
@@ -572,25 +607,32 @@ void BrowserMediaPlayerManager::OnGenerateKeyRequest(
base::Bind(&BrowserMediaPlayerManager::GenerateKeyIfAllowed,
weak_ptr_factory_.GetWeakPtr(),
media_keys_id,
- reference_id,
+ session_id,
type,
init_data));
}
-void BrowserMediaPlayerManager::OnAddKey(int media_keys_id,
- uint32 reference_id,
- const std::vector<uint8>& key,
- const std::vector<uint8>& init_data) {
+void BrowserMediaPlayerManager::OnUpdateSession(
+ int media_keys_id,
+ uint32 session_id,
+ const std::vector<uint8>& response) {
MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
if (!drm_bridge) {
DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
- OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0);
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
- drm_bridge->AddKey(reference_id,
- &key[0], key.size(),
- &init_data[0], init_data.size());
+ if (response.size() > kEmeResponseMaximum) {
+ DLOG(WARNING) << "Response for ID: " << media_keys_id
+ << " too long: " << response.size();
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
+ return;
+ }
+
+ drm_bridge->UpdateSession(session_id, &response[0], response.size());
// In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
// is the same as the |player_id|.
// TODO(xhwang): Separate |media_keys_id| and |player_id|.
@@ -599,17 +641,17 @@ void BrowserMediaPlayerManager::OnAddKey(int media_keys_id,
player->OnKeyAdded();
}
-void BrowserMediaPlayerManager::OnCancelKeyRequest(
- int media_keys_id,
- uint32 reference_id) {
+void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id,
+ uint32 session_id) {
MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
if (!drm_bridge) {
DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
- OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0);
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
- drm_bridge->CancelKeyRequest(reference_id);
+ drm_bridge->ReleaseSession(session_id);
}
void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) {
@@ -672,7 +714,7 @@ void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id,
scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create(
media_keys_id, uuid, frame_url, security_level, this));
if (!drm_bridge) {
- // This failure will be discovered and reported by OnGenerateKeyRequest()
+ // This failure will be discovered and reported by OnCreateSession()
// as GetDrmBridge() will return null.
DVLOG(1) << "failed to create drm bridge.";
return;
@@ -706,7 +748,7 @@ void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id,
void BrowserMediaPlayerManager::GenerateKeyIfAllowed(
int media_keys_id,
- uint32 reference_id,
+ uint32 session_id,
const std::string& type,
const std::vector<uint8>& init_data,
bool allowed) {
@@ -716,13 +758,13 @@ void BrowserMediaPlayerManager::GenerateKeyIfAllowed(
MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
if (!drm_bridge) {
DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
- OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0);
+ OnSessionError(
+ media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
media_keys_ids_pending_approval_.erase(media_keys_id);
media_keys_ids_approved_.insert(media_keys_id);
- drm_bridge->GenerateKeyRequest(
- reference_id, type, &init_data[0], init_data.size());
+ drm_bridge->CreateSession(session_id, type, &init_data[0], init_data.size());
// TODO(qinmin): currently |media_keys_id| and player ID are identical.
// This might not be true in the future.
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h
index bd5ad7800d..36ed0618ea 100644
--- a/content/browser/media/android/browser_media_player_manager.h
+++ b/content/browser/media/android/browser_media_player_manager.h
@@ -90,19 +90,19 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual media::MediaDrmBridge* GetDrmBridge(int media_keys_id) OVERRIDE;
virtual void DestroyAllMediaPlayers() OVERRIDE;
virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE;
- virtual void OnKeyAdded(int media_keys_id,
- uint32 reference_id) OVERRIDE;
- virtual void OnKeyError(int media_keys_id,
- uint32 reference_id,
- media::MediaKeys::KeyError error_code,
- int system_code) OVERRIDE;
- virtual void OnKeyMessage(int media_keys_id,
- uint32 reference_id,
- const std::vector<uint8>& message,
- const std::string& destination_url) OVERRIDE;
- virtual void OnSetSessionId(int media_keys_id,
- uint32 reference_id,
- const std::string& session_id) OVERRIDE;
+ virtual void OnSessionCreated(int media_keys_id,
+ uint32 session_id,
+ const std::string& web_session_id) OVERRIDE;
+ virtual void OnSessionMessage(int media_keys_id,
+ uint32 session_id,
+ const std::vector<uint8>& message,
+ const std::string& destination_url) OVERRIDE;
+ virtual void OnSessionReady(int media_keys_id, uint32 session_id) OVERRIDE;
+ virtual void OnSessionClosed(int media_keys_id, uint32 session_id) OVERRIDE;
+ virtual void OnSessionError(int media_keys_id,
+ uint32 session_id,
+ media::MediaKeys::KeyError error_code,
+ int system_code) OVERRIDE;
#if defined(GOOGLE_TV)
void AttachExternalVideoSurface(int player_id, jobject surface);
@@ -135,15 +135,14 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
void OnInitializeCDM(int media_keys_id,
const std::vector<uint8>& uuid,
const GURL& frame_url);
- void OnGenerateKeyRequest(int media_keys_id,
- uint32 reference_id,
- const std::string& type,
- const std::vector<uint8>& init_data);
- void OnAddKey(int media_keys_id,
- uint32 reference_id,
- const std::vector<uint8>& key,
- const std::vector<uint8>& init_data);
- void OnCancelKeyRequest(int media_keys_id, uint32 reference_id);
+ void OnCreateSession(int media_keys_id,
+ uint32 session_id,
+ const std::string& type,
+ const std::vector<uint8>& init_data);
+ void OnUpdateSession(int media_keys_id,
+ uint32 session_id,
+ const std::vector<uint8>& response);
+ void OnReleaseSession(int media_keys_id, uint32 session_id);
void OnSetMediaKeys(int player_id, int media_keys_id);
#if defined(GOOGLE_TV)
@@ -175,7 +174,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
private:
void GenerateKeyIfAllowed(int media_keys_id,
- uint32 reference_id,
+ uint32 session_id,
const std::string& type,
const std::vector<uint8>& init_data,
bool allowed);
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index 215b3e7ff2..0655823363 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -59,13 +59,13 @@ void MediaBrowserTest::RunMediaTestPage(
}
void MediaBrowserTest::RunTest(const GURL& gurl, const char* expected) {
- const string16 expected_title = ASCIIToUTF16(expected);
+ const base::string16 expected_title = ASCIIToUTF16(expected);
DVLOG(1) << "Running test URL: " << gurl;
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
AddWaitForTitles(&title_watcher);
NavigateToURL(shell(), gurl);
- string16 final_title = title_watcher.WaitAndGetTitle();
+ base::string16 final_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, final_title);
}
diff --git a/content/browser/media_devices_monitor.cc b/content/browser/media/media_devices_monitor.cc
index 72c3b4b1ce..9f2c18353f 100644
--- a/content/browser/media_devices_monitor.cc
+++ b/content/browser/media/media_devices_monitor.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,8 +12,7 @@ namespace content {
namespace {
void EnsureMonitorCaptureDevicesInternal(
MediaStreamManager* media_stream_manager) {
- media_stream_manager->EnumerateDevices(
- NULL, -1, -1, -1, MEDIA_DEVICE_AUDIO_CAPTURE, GURL());
+ media_stream_manager->EnsureDeviceMonitorStarted();
}
}
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index 1e0538e49f..1ee42d1757 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -17,8 +17,8 @@ namespace {
static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals =
LAZY_INSTANCE_INITIALIZER;
-string16 SerializeUpdate(const std::string& function,
- const base::Value* value) {
+base::string16 SerializeUpdate(const std::string& function,
+ const base::Value* value) {
return content::WebUI::GetJavascriptCall(
function, std::vector<const base::Value*>(1, value));
}
@@ -185,7 +185,7 @@ void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) {
}
void MediaInternals::SendEverything() {
- string16 everything_update;
+ base::string16 everything_update;
{
base::AutoLock auto_lock(lock_);
everything_update = SerializeUpdate(
@@ -194,7 +194,7 @@ void MediaInternals::SendEverything() {
SendUpdate(everything_update);
}
-void MediaInternals::SendUpdate(const string16& update) {
+void MediaInternals::SendUpdate(const base::string16& update) {
// SendUpdate() may be called from any thread, but must run on the IO thread.
// TODO(dalecurtis): This is pretty silly since the update callbacks simply
// forward the calls to the UI thread. We should avoid the extra hop.
diff --git a/content/browser/media/media_internals.h b/content/browser/media/media_internals.h
index 8a179e0197..c0f144a5b8 100644
--- a/content/browser/media/media_internals.h
+++ b/content/browser/media/media_internals.h
@@ -37,7 +37,7 @@ class CONTENT_EXPORT MediaInternals
const std::vector<media::MediaLogEvent>& events);
// Called with the update string.
- typedef base::Callback<void(const string16&)> UpdateCallback;
+ typedef base::Callback<void(const base::string16&)> UpdateCallback;
// Add/remove update callbacks (see above). Must be called on the IO thread.
void AddUpdateCallback(const UpdateCallback& callback);
@@ -59,7 +59,7 @@ class CONTENT_EXPORT MediaInternals
// Sends |update| to each registered UpdateCallback. Safe to call from any
// thread, but will forward to the IO thread.
- void SendUpdate(const string16& update);
+ void SendUpdate(const base::string16& update);
// Caches |value| under |cache_key| so that future SendEverything() calls will
// include the current data. Calls JavaScript |function|(|value|) for each
diff --git a/content/browser/media/media_internals_handler.cc b/content/browser/media/media_internals_handler.cc
index a45dd4f51e..9a3e7be214 100644
--- a/content/browser/media/media_internals_handler.cc
+++ b/content/browser/media/media_internals_handler.cc
@@ -38,12 +38,12 @@ void MediaInternalsMessageHandler::OnGetEverything(
proxy_->GetEverything();
}
-void MediaInternalsMessageHandler::OnUpdate(const string16& update) {
+void MediaInternalsMessageHandler::OnUpdate(const base::string16& update) {
// Don't try to execute JavaScript in a RenderView that no longer exists nor
// if the chrome://media-internals page hasn't finished loading.
RenderViewHost* host = web_ui()->GetWebContents()->GetRenderViewHost();
if (host && page_load_complete_)
- host->ExecuteJavascriptInWebFrame(string16(), update);
+ host->ExecuteJavascriptInWebFrame(base::string16(), update);
}
} // namespace content
diff --git a/content/browser/media/media_internals_handler.h b/content/browser/media/media_internals_handler.h
index 8ea6f88a46..265c1224d7 100644
--- a/content/browser/media/media_internals_handler.h
+++ b/content/browser/media/media_internals_handler.h
@@ -30,7 +30,7 @@ class MediaInternalsMessageHandler : public WebUIMessageHandler {
void OnGetEverything(const base::ListValue* list);
// MediaInternals message handlers.
- void OnUpdate(const string16& update);
+ void OnUpdate(const base::string16& update);
private:
scoped_refptr<MediaInternalsProxy> proxy_;
diff --git a/content/browser/media/media_internals_proxy.cc b/content/browser/media/media_internals_proxy.cc
index d0e0622b41..49456ab498 100644
--- a/content/browser/media/media_internals_proxy.cc
+++ b/content/browser/media/media_internals_proxy.cc
@@ -69,7 +69,7 @@ void MediaInternalsProxy::GetEverything() {
CallJavaScriptFunctionOnUIThread("media.onReceiveConstants", GetConstants());
}
-void MediaInternalsProxy::OnUpdate(const string16& update) {
+void MediaInternalsProxy::OnUpdate(const base::string16& update) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -140,7 +140,7 @@ void MediaInternalsProxy::GetEverythingOnIOThread() {
MediaInternals::GetInstance()->SendEverything();
}
-void MediaInternalsProxy::UpdateUIOnUIThread(const string16& update) {
+void MediaInternalsProxy::UpdateUIOnUIThread(const base::string16& update) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Don't forward updates to a destructed UI.
if (handler_)
@@ -175,7 +175,7 @@ void MediaInternalsProxy::CallJavaScriptFunctionOnUIThread(
scoped_ptr<base::Value> args_value(args);
std::vector<const base::Value*> args_vector;
args_vector.push_back(args_value.get());
- string16 update = WebUI::GetJavascriptCall(function, args_vector);
+ base::string16 update = WebUI::GetJavascriptCall(function, args_vector);
UpdateUIOnUIThread(update);
}
diff --git a/content/browser/media/media_internals_proxy.h b/content/browser/media/media_internals_proxy.h
index 5d173b3e73..b737b858a3 100644
--- a/content/browser/media/media_internals_proxy.h
+++ b/content/browser/media/media_internals_proxy.h
@@ -49,7 +49,7 @@ class MediaInternalsProxy
void GetEverything();
// MediaInternals callback. Called on the IO thread.
- void OnUpdate(const string16& update);
+ void OnUpdate(const base::string16& update);
// net::NetLog::ThreadSafeObserver implementation. Callable from any thread:
virtual void OnAddEntry(const net::NetLog::Entry& entry) OVERRIDE;
@@ -65,7 +65,7 @@ class MediaInternalsProxy
void ObserveMediaInternalsOnIOThread();
void StopObservingMediaInternalsOnIOThread();
void GetEverythingOnIOThread();
- void UpdateUIOnUIThread(const string16& update);
+ void UpdateUIOnUIThread(const base::string16& update);
// Put |entry| on a list of events to be sent to the page.
void AddNetEventOnUIThread(base::Value* entry);
diff --git a/content/browser/media/media_internals_unittest.cc b/content/browser/media/media_internals_unittest.cc
index e16124bd09..2947104cad 100644
--- a/content/browser/media/media_internals_unittest.cc
+++ b/content/browser/media/media_internals_unittest.cc
@@ -45,7 +45,7 @@ class MediaInternalsTest
protected:
// Extracts and deserializes the JSON update data; merges into |update_data_|.
- void UpdateCallbackImpl(const string16& update) {
+ void UpdateCallbackImpl(const base::string16& update) {
// Each update string looks like "<JavaScript Function Name>({<JSON>});", to
// use the JSON reader we need to strip out the JavaScript code.
std::string utf8_update = base::UTF16ToUTF8(update);
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc
index bfb96e1519..47847a7d53 100644
--- a/content/browser/media/webrtc_browsertest.cc
+++ b/content/browser/media/webrtc_browsertest.cc
@@ -14,6 +14,7 @@
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
+#include "media/audio/audio_manager.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/perf/perf_test.h"
@@ -21,6 +22,14 @@
#include "base/win/windows_version.h"
#endif
+const char kForceIsac16K[] =
+#ifdef OS_ANDROID
+ // The default audio codec, Opus, doesn't work on Android.
+ "true";
+#else
+ "false";
+#endif
+
namespace {
static const char kGetUserMediaAndStop[] = "getUserMediaAndStop";
@@ -130,7 +139,7 @@ class WebrtcBrowserTest: public ContentBrowserTest {
}
void ExpectTitle(const std::string& expected_title) const {
- string16 expected_title16(ASCIIToUTF16(expected_title));
+ base::string16 expected_title16(ASCIIToUTF16(expected_title));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
@@ -558,4 +567,55 @@ IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest, AddTwoMediaStreamsToOnePC) {
ExpectTitle("OK");
}
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+ EstablishAudioVideoCallAndMeasureOutputLevel) {
+ if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
+ // Bots with no output devices will force the audio code into a different
+ // path where it doesn't manage to set either the low or high latency path.
+ // This test will compute useless values in that case, so skip running on
+ // such bots (see crbug.com/326338).
+ LOG(INFO) << "Missing output devices: skipping test...";
+ return;
+ }
+
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFakeDeviceForMediaStream))
+ << "Must run with fake devices since the test will explicitly look "
+ << "for the fake device signal.";
+
+ GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
+ NavigateToURL(shell(), url);
+
+ EXPECT_TRUE(ExecuteJavascript(
+ base::StringPrintf("callAndEnsureAudioIsPlaying(%s);", kForceIsac16K)));
+ ExpectTitle("OK");
+}
+
+IN_PROC_BROWSER_TEST_F(WebrtcBrowserTest,
+ EstablishAudioVideoCallAndVerifyMutingWorks) {
+ if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
+ // Bots with no output devices will force the audio code into a different
+ // path where it doesn't manage to set either the low or high latency path.
+ // This test will compute useless values in that case, so skip running on
+ // such bots (see crbug.com/326338).
+ LOG(INFO) << "Missing output devices: skipping test...";
+ return;
+ }
+
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFakeDeviceForMediaStream))
+ << "Must run with fake devices since the test will explicitly look "
+ << "for the fake device signal.";
+
+ GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
+ NavigateToURL(shell(), url);
+
+ EXPECT_TRUE(ExecuteJavascript(
+ base::StringPrintf("callAndEnsureAudioMutingWorks(%s);",
+ kForceIsac16K)));
+ ExpectTitle("OK");
+}
+
} // namespace content
diff --git a/content/browser/media/webrtc_identity_store_backend.cc b/content/browser/media/webrtc_identity_store_backend.cc
index 5aed5207a0..d599dcda74 100644
--- a/content/browser/media/webrtc_identity_store_backend.cc
+++ b/content/browser/media/webrtc_identity_store_backend.cc
@@ -369,7 +369,7 @@ void WebRTCIdentityStoreBackend::SqlLiteStorage::Load(IdentityMap* out_map) {
// Ensure the parent directory for storing certs is created before reading
// from it.
const base::FilePath dir = path_.DirName();
- if (!base::PathExists(dir) && !file_util::CreateDirectory(dir)) {
+ if (!base::PathExists(dir) && !base::CreateDirectory(dir)) {
DLOG(ERROR) << "Unable to open DB file path.";
return;
}
diff --git a/content/browser/media/webrtc_internals_browsertest.cc b/content/browser/media/webrtc_internals_browsertest.cc
index b45827623b..0d279b3075 100644
--- a/content/browser/media/webrtc_internals_browsertest.cc
+++ b/content/browser/media/webrtc_internals_browsertest.cc
@@ -145,7 +145,7 @@ class MAYBE_WebRTCInternalsBrowserTest: public ContentBrowserTest {
}
void ExpectTitle(const std::string& expected_title) const {
- string16 expected_title16(ASCIIToUTF16(expected_title));
+ base::string16 expected_title16(ASCIIToUTF16(expected_title));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
diff --git a/content/browser/media/webrtc_internals_message_handler.cc b/content/browser/media/webrtc_internals_message_handler.cc
index 2ba7522738..8cf8579028 100644
--- a/content/browser/media/webrtc_internals_message_handler.cc
+++ b/content/browser/media/webrtc_internals_message_handler.cc
@@ -68,11 +68,11 @@ void WebRTCInternalsMessageHandler::OnUpdate(const std::string& command,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
std::vector<const base::Value*> args_vector;
args_vector.push_back(args);
- string16 update = WebUI::GetJavascriptCall(command, args_vector);
+ base::string16 update = WebUI::GetJavascriptCall(command, args_vector);
RenderViewHost* host = web_ui()->GetWebContents()->GetRenderViewHost();
if (host)
- host->ExecuteJavascriptInWebFrame(string16(), update);
+ host->ExecuteJavascriptInWebFrame(base::string16(), update);
}
} // namespace content
diff --git a/content/browser/message_port_service.cc b/content/browser/message_port_service.cc
index bc2a1ac826..0d9f6084e8 100644
--- a/content/browser/message_port_service.cc
+++ b/content/browser/message_port_service.cc
@@ -108,7 +108,7 @@ void MessagePortService::Entangle(int local_message_port_id,
void MessagePortService::PostMessage(
int sender_message_port_id,
- const string16& message,
+ const base::string16& message,
const std::vector<int>& sent_message_port_ids) {
if (!message_ports_.count(sender_message_port_id)) {
NOTREACHED();
@@ -130,7 +130,7 @@ void MessagePortService::PostMessage(
void MessagePortService::PostMessageTo(
int message_port_id,
- const string16& message,
+ const base::string16& message,
const std::vector<int>& sent_message_port_ids) {
if (!message_ports_.count(message_port_id)) {
NOTREACHED();
diff --git a/content/browser/message_port_service.h b/content/browser/message_port_service.h
index 55e536c1dd..668959167f 100644
--- a/content/browser/message_port_service.h
+++ b/content/browser/message_port_service.h
@@ -19,7 +19,8 @@ class MessagePortMessageFilter;
class MessagePortService {
public:
- typedef std::vector<std::pair<string16, std::vector<int> > > QueuedMessages;
+ typedef std::vector<std::pair<base::string16, std::vector<int> > >
+ QueuedMessages;
// Returns the MessagePortService singleton.
static MessagePortService* GetInstance();
@@ -31,7 +32,7 @@ class MessagePortService {
void Destroy(int message_port_id);
void Entangle(int local_message_port_id, int remote_message_port_id);
void PostMessage(int sender_message_port_id,
- const string16& message,
+ const base::string16& message,
const std::vector<int>& sent_message_port_ids);
void QueueMessages(int message_port_id);
void SendQueuedMessages(int message_port_id,
@@ -56,7 +57,7 @@ class MessagePortService {
~MessagePortService();
void PostMessageTo(int message_port_id,
- const string16& message,
+ const base::string16& message,
const std::vector<int>& sent_message_port_ids);
// Handles the details of removing a message port id. Before calling this,
diff --git a/content/browser/net/sqlite_persistent_cookie_store.cc b/content/browser/net/sqlite_persistent_cookie_store.cc
index 1c0a8e7a72..a337733922 100644
--- a/content/browser/net/sqlite_persistent_cookie_store.cc
+++ b/content/browser/net/sqlite_persistent_cookie_store.cc
@@ -544,12 +544,12 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
base::Time start = base::Time::Now();
const base::FilePath dir = path_.DirName();
- if (!base::PathExists(dir) && !file_util::CreateDirectory(dir)) {
+ if (!base::PathExists(dir) && !base::CreateDirectory(dir)) {
return false;
}
int64 db_size = 0;
- if (file_util::GetFileSize(path_, &db_size))
+ if (base::GetFileSize(path_, &db_size))
UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 );
db_.reset(new sql::Connection);
diff --git a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
index 4adb790668..49ac64be46 100644
--- a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
+++ b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
@@ -289,7 +289,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
// whether the DB file has been modified by checking its size.
base::FilePath path = temp_dir_.path().Append(kCookieFilename);
base::PlatformFileInfo info;
- ASSERT_TRUE(file_util::GetFileInfo(path, &info));
+ ASSERT_TRUE(base::GetFileInfo(path, &info));
int64 base_size = info.size;
// Write some large cookies, so the DB will have to expand by several KB.
@@ -304,7 +304,7 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
Flush();
// We forced a write, so now the file will be bigger.
- ASSERT_TRUE(file_util::GetFileInfo(path, &info));
+ ASSERT_TRUE(base::GetFileInfo(path, &info));
ASSERT_GT(info.size, base_size);
}
diff --git a/content/browser/plugin_browsertest.cc b/content/browser/plugin_browsertest.cc
index 2a846f124f..204a143203 100644
--- a/content/browser/plugin_browsertest.cc
+++ b/content/browser/plugin_browsertest.cc
@@ -83,12 +83,12 @@ class PluginTest : public ContentBrowserTest {
}
static void LoadAndWaitInWindow(Shell* window, const GURL& url) {
- string16 expected_title(ASCIIToUTF16("OK"));
+ base::string16 expected_title(ASCIIToUTF16("OK"));
TitleWatcher title_watcher(window->web_contents(), expected_title);
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("plugin_not_found"));
NavigateToURL(window, url);
- string16 title = title_watcher.WaitAndGetTitle();
+ base::string16 title = title_watcher.WaitAndGetTitle();
if (title == ASCIIToUTF16("plugin_not_found")) {
const testing::TestInfo* const test_info =
testing::UnitTest::GetInstance()->current_test_info();
@@ -170,7 +170,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest,
MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) {
NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html"));
- string16 expected_title(ASCIIToUTF16("OK"));
+ base::string16 expected_title(ASCIIToUTF16("OK"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
SimulateMouseClick(shell()->web_contents(), 0,
@@ -201,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) {
// race condition where the alert can come up before we start watching for it.
shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html"));
- string16 expected_title(ASCIIToUTF16("OK"));
+ base::string16 expected_title(ASCIIToUTF16("OK"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
@@ -408,7 +408,7 @@ IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_PluginConvertPointTest) {
NavigateToURL(shell(), GetURL("convert_point.html"));
- string16 expected_title(ASCIIToUTF16("OK"));
+ base::string16 expected_title(ASCIIToUTF16("OK"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
// TODO(stuartmorgan): When the automation system supports sending clicks,
diff --git a/content/browser/plugin_loader_posix_unittest.cc b/content/browser/plugin_loader_posix_unittest.cc
index 8f90723212..13620f74dd 100644
--- a/content/browser/plugin_loader_posix_unittest.cc
+++ b/content/browser/plugin_loader_posix_unittest.cc
@@ -64,11 +64,11 @@ class PluginLoaderPosixTest : public testing::Test {
public:
PluginLoaderPosixTest()
: plugin1_(ASCIIToUTF16("plugin1"), base::FilePath("/tmp/one.plugin"),
- ASCIIToUTF16("1.0"), string16()),
+ ASCIIToUTF16("1.0"), base::string16()),
plugin2_(ASCIIToUTF16("plugin2"), base::FilePath("/tmp/two.plugin"),
- ASCIIToUTF16("2.0"), string16()),
+ ASCIIToUTF16("2.0"), base::string16()),
plugin3_(ASCIIToUTF16("plugin3"), base::FilePath("/tmp/three.plugin"),
- ASCIIToUTF16("3.0"), string16()),
+ ASCIIToUTF16("3.0"), base::string16()),
file_thread_(BrowserThread::FILE, &message_loop_),
io_thread_(BrowserThread::IO, &message_loop_),
plugin_loader_(new MockPluginLoaderPosix) {
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc
index 1ddcf4012a..74feedeec3 100644
--- a/content/browser/plugin_service_impl.cc
+++ b/content/browser/plugin_service_impl.cc
@@ -298,7 +298,12 @@ PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess(
START_NPAPI_FLASH_AT_LEAST_ONCE,
FLASH_USAGE_ENUM_COUNT);
}
-
+#if defined(OS_CHROMEOS)
+ // TODO(ihf): Move to an earlier place once crbug.com/314301 is fixed. For now
+ // we still want Plugin.FlashUsage recorded if we end up here.
+ LOG(WARNING) << "Refusing to start npapi plugin on ChromeOS.";
+ return NULL;
+#endif
// This plugin isn't loaded by any plugin process, so create a new process.
scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
if (!new_host->Init(info)) {
@@ -314,8 +319,10 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
const base::FilePath& profile_data_directory) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path))
+ if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) {
+ VLOG(1) << "Unable to load ppapi plugin: " << plugin_path.MaybeAsASCII();
return NULL;
+ }
PpapiPluginProcessHost* plugin_host =
FindPpapiPluginProcess(plugin_path, profile_data_directory);
@@ -324,8 +331,11 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
// Validate that the plugin is actually registered.
PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
- if (!info)
+ if (!info) {
+ VLOG(1) << "Unable to find ppapi plugin registration for: "
+ << plugin_path.MaybeAsASCII();
return NULL;
+ }
// Record when PPAPI Flash process is started for the first time.
static bool counted = false;
@@ -337,8 +347,14 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess(
}
// This plugin isn't loaded by any plugin process, so create a new process.
- return PpapiPluginProcessHost::CreatePluginHost(
+ plugin_host = PpapiPluginProcessHost::CreatePluginHost(
*info, profile_data_directory);
+ if (!plugin_host) {
+ VLOG(1) << "Unable to create ppapi plugin process for: "
+ << plugin_path.MaybeAsASCII();
+ }
+
+ return plugin_host;
}
PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
@@ -367,7 +383,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess(
void PluginServiceImpl::OpenChannelToNpapiPlugin(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
@@ -379,7 +395,7 @@ void PluginServiceImpl::OpenChannelToNpapiPlugin(
// Make sure plugins are loaded if necessary.
PluginServiceFilterParams params = {
render_process_id,
- render_view_id,
+ render_frame_id,
page_url,
client->GetResourceContext()
};
@@ -430,14 +446,14 @@ void PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin(
const std::string& mime_type,
PluginProcessHost::Client* client,
const std::vector<WebPluginInfo>&) {
- GetAllowedPluginForOpenChannelToPlugin(params.render_process_id,
- params.render_view_id, url, params.page_url, mime_type, client,
- params.resource_context);
+ GetAllowedPluginForOpenChannelToPlugin(
+ params.render_process_id, params.render_frame_id, url, params.page_url,
+ mime_type, client, params.resource_context);
}
void PluginServiceImpl::GetAllowedPluginForOpenChannelToPlugin(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
@@ -446,7 +462,7 @@ void PluginServiceImpl::GetAllowedPluginForOpenChannelToPlugin(
WebPluginInfo info;
bool allow_wildcard = true;
bool found = GetPluginInfo(
- render_process_id, render_view_id, resource_context,
+ render_process_id, render_frame_id, resource_context,
url, page_url, mime_type, allow_wildcard,
NULL, &info, NULL);
base::FilePath plugin_path;
@@ -498,7 +514,7 @@ bool PluginServiceImpl::GetPluginInfoArray(
}
bool PluginServiceImpl::GetPluginInfo(int render_process_id,
- int render_view_id,
+ int render_frame_id,
ResourceContext* context,
const GURL& url,
const GURL& page_url,
@@ -516,7 +532,7 @@ bool PluginServiceImpl::GetPluginInfo(int render_process_id,
for (size_t i = 0; i < plugins.size(); ++i) {
if (!filter_ || filter_->IsPluginAvailable(render_process_id,
- render_view_id,
+ render_frame_id,
context,
url,
page_url,
@@ -547,9 +563,9 @@ bool PluginServiceImpl::GetPluginInfoByPath(const base::FilePath& plugin_path,
return false;
}
-string16 PluginServiceImpl::GetPluginDisplayNameByPath(
+base::string16 PluginServiceImpl::GetPluginDisplayNameByPath(
const base::FilePath& path) {
- string16 plugin_name = path.LossyDisplayName();
+ base::string16 plugin_name = path.LossyDisplayName();
WebPluginInfo info;
if (PluginService::GetInstance()->GetPluginInfoByPath(path, &info) &&
!info.name.empty()) {
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h
index 11fb257e99..d8e3de62ae 100644
--- a/content/browser/plugin_service_impl.h
+++ b/content/browser/plugin_service_impl.h
@@ -59,7 +59,7 @@ struct PepperPluginInfo;
// surpass that limit.
struct PluginServiceFilterParams {
int render_process_id;
- int render_view_id;
+ int render_frame_id;
GURL page_url;
ResourceContext* resource_context;
};
@@ -80,7 +80,7 @@ class CONTENT_EXPORT PluginServiceImpl
std::vector<WebPluginInfo>* info,
std::vector<std::string>* actual_mime_types) OVERRIDE;
virtual bool GetPluginInfo(int render_process_id,
- int render_view_id,
+ int render_frame_id,
ResourceContext* context,
const GURL& url,
const GURL& page_url,
@@ -91,7 +91,7 @@ class CONTENT_EXPORT PluginServiceImpl
std::string* actual_mime_type) OVERRIDE;
virtual bool GetPluginInfoByPath(const base::FilePath& plugin_path,
WebPluginInfo* info) OVERRIDE;
- virtual string16 GetPluginDisplayNameByPath(
+ virtual base::string16 GetPluginDisplayNameByPath(
const base::FilePath& path) OVERRIDE;
virtual void GetPlugins(const GetPluginsCallback& callback) OVERRIDE;
virtual PepperPluginInfo* GetRegisteredPpapiPluginInfo(
@@ -139,7 +139,7 @@ class CONTENT_EXPORT PluginServiceImpl
// a new plugin process if necessary. This must be called on the IO thread
// or else a deadlock can occur.
void OpenChannelToNpapiPlugin(int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
@@ -195,7 +195,7 @@ class CONTENT_EXPORT PluginServiceImpl
// Helper so we can do the plugin lookup on the FILE thread.
void GetAllowedPluginForOpenChannelToPlugin(
int render_process_id,
- int render_view_id,
+ int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
diff --git a/content/browser/power_save_blocker_win.cc b/content/browser/power_save_blocker_win.cc
index fce72c65b6..cf9bb02301 100644
--- a/content/browser/power_save_blocker_win.cc
+++ b/content/browser/power_save_blocker_win.cc
@@ -39,7 +39,7 @@ HANDLE CreatePowerRequest(POWER_REQUEST_TYPE type, const std::string& reason) {
if (!PowerCreateRequestFn || !PowerSetRequestFn)
return INVALID_HANDLE_VALUE;
}
- string16 wide_reason = ASCIIToUTF16(reason);
+ base::string16 wide_reason = ASCIIToUTF16(reason);
REASON_CONTEXT context = {0};
context.Version = POWER_REQUEST_CONTEXT_VERSION;
context.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index fbf512a741..cb408af5b8 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -117,6 +117,7 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreatePluginHost(
const base::FilePath& profile_data_directory) {
PpapiPluginProcessHost* plugin_host = new PpapiPluginProcessHost(
info, profile_data_directory);
+ DCHECK(plugin_host);
if (plugin_host->Init(info))
return plugin_host;
@@ -178,7 +179,7 @@ void PpapiPluginProcessHost::DidDeleteOutOfProcessInstance(
// static
void PpapiPluginProcessHost::FindByName(
- const string16& name,
+ const base::string16& name,
std::vector<PpapiPluginProcessHost*>* hosts) {
for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
if (iter->process_.get() && iter->process_->GetData().name == name)
@@ -253,8 +254,10 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
}
std::string channel_id = process_->GetHost()->CreateChannel();
- if (channel_id.empty())
+ if (channel_id.empty()) {
+ VLOG(1) << "Could not create pepper host channel.";
return false;
+ }
const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
CommandLine::StringType plugin_launcher =
@@ -267,8 +270,10 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) {
int flags = ChildProcessHost::CHILD_NORMAL;
#endif
base::FilePath exe_path = ChildProcessHost::GetChildPath(flags);
- if (exe_path.empty())
+ if (exe_path.empty()) {
+ VLOG(1) << "Pepper plugin exe path is empty.";
return false;
+ }
CommandLine* cmd_line = new CommandLine(exe_path);
cmd_line->AppendSwitchASCII(switches::kProcessType,
@@ -357,10 +362,12 @@ void PpapiPluginProcessHost::RequestPluginChannel(Client* client) {
}
void PpapiPluginProcessHost::OnProcessLaunched() {
+ VLOG(2) << "ppapi plugin process launched.";
host_impl_->set_plugin_process_handle(process_->GetHandle());
}
void PpapiPluginProcessHost::OnProcessCrashed(int exit_code) {
+ VLOG(1) << "ppapi plugin process crashed.";
PluginServiceImpl::GetInstance()->RegisterPluginCrash(plugin_path_);
}
@@ -391,8 +398,8 @@ void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) {
// Called when the browser <--> plugin channel has an error. This normally
// means the plugin has crashed.
void PpapiPluginProcessHost::OnChannelError() {
- DVLOG(1) << "PpapiPluginProcessHost" << (is_broker_ ? "[broker]" : "")
- << "::OnChannelError()";
+ VLOG(1) << "PpapiPluginProcessHost" << (is_broker_ ? "[broker]" : "")
+ << "::OnChannelError()";
// We don't need to notify the renderers that were communicating with the
// plugin since they have their own channels which will go into the error
// state at the same time. Instead, we just need to notify any renderers
diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h
index 87c79c31d2..594c12f615 100644
--- a/content/browser/ppapi_plugin_process_host.h
+++ b/content/browser/ppapi_plugin_process_host.h
@@ -92,7 +92,7 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate,
// Returns the instances that match the specified process name.
// It can only be called on the IO thread.
- static void FindByName(const string16& name,
+ static void FindByName(const base::string16& name,
std::vector<PpapiPluginProcessHost*>* hosts);
// IPC::Sender implementation:
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc
index ae365d5cfd..6ba95f8f12 100644
--- a/content/browser/renderer_host/clipboard_message_filter.cc
+++ b/content/browser/renderer_host/clipboard_message_filter.cc
@@ -145,9 +145,10 @@ void ClipboardMessageFilter::OnGetSequenceNumber(ui::ClipboardType type,
*sequence_number = GetClipboard()->GetSequenceNumber(type);
}
-void ClipboardMessageFilter::OnReadAvailableTypes(ui::ClipboardType type,
- std::vector<string16>* types,
- bool* contains_filenames) {
+void ClipboardMessageFilter::OnReadAvailableTypes(
+ ui::ClipboardType type,
+ std::vector<base::string16>* types,
+ bool* contains_filenames) {
GetClipboard()->ReadAvailableTypes(type, types, contains_filenames);
}
@@ -163,7 +164,7 @@ void ClipboardMessageFilter::OnClear(ui::ClipboardType type) {
}
void ClipboardMessageFilter::OnReadText(ui::ClipboardType type,
- string16* result) {
+ base::string16* result) {
GetClipboard()->ReadText(type, result);
}
@@ -173,7 +174,7 @@ void ClipboardMessageFilter::OnReadAsciiText(ui::ClipboardType type,
}
void ClipboardMessageFilter::OnReadHTML(ui::ClipboardType type,
- string16* markup,
+ base::string16* markup,
GURL* url,
uint32* fragment_start,
uint32* fragment_end) {
@@ -224,8 +225,8 @@ void ClipboardMessageFilter::OnReadImageReply(
}
void ClipboardMessageFilter::OnReadCustomData(ui::ClipboardType clipboard_type,
- const string16& type,
- string16* result) {
+ const base::string16& type,
+ base::string16* result) {
GetClipboard()->ReadCustomData(clipboard_type, type, result);
}
diff --git a/content/browser/renderer_host/clipboard_message_filter.h b/content/browser/renderer_host/clipboard_message_filter.h
index 3ae7d1b5c1..dd2784be53 100644
--- a/content/browser/renderer_host/clipboard_message_filter.h
+++ b/content/browser/renderer_host/clipboard_message_filter.h
@@ -39,12 +39,12 @@ class ClipboardMessageFilter : public BrowserMessageFilter {
bool* result);
void OnClear(ui::ClipboardType type);
void OnReadAvailableTypes(ui::ClipboardType type,
- std::vector<string16>* types,
+ std::vector<base::string16>* types,
bool* contains_filenames);
- void OnReadText(ui::ClipboardType type, string16* result);
+ void OnReadText(ui::ClipboardType type, base::string16* result);
void OnReadAsciiText(ui::ClipboardType type, std::string* result);
void OnReadHTML(ui::ClipboardType type,
- string16* markup,
+ base::string16* markup,
GURL* url,
uint32* fragment_start,
uint32* fragment_end);
@@ -52,13 +52,13 @@ class ClipboardMessageFilter : public BrowserMessageFilter {
void OnReadImage(ui::ClipboardType type, IPC::Message* reply_msg);
void OnReadImageReply(const SkBitmap& bitmap, IPC::Message* reply_msg);
void OnReadCustomData(ui::ClipboardType clipboard_type,
- const string16& type,
- string16* result);
+ const base::string16& type,
+ base::string16* result);
void OnReadData(const ui::Clipboard::FormatType& format,
std::string* data);
#if defined(OS_MACOSX)
- void OnFindPboardWriteString(const string16& text);
+ void OnFindPboardWriteString(const base::string16& text);
#endif
// We have our own clipboard because we want to access the clipboard on the
diff --git a/content/browser/renderer_host/clipboard_message_filter_mac.mm b/content/browser/renderer_host/clipboard_message_filter_mac.mm
index ee8f5a3e42..3c59d31f40 100644
--- a/content/browser/renderer_host/clipboard_message_filter_mac.mm
+++ b/content/browser/renderer_host/clipboard_message_filter_mac.mm
@@ -40,7 +40,8 @@ class WriteFindPboardWrapper {
} // namespace
// Called on the IO thread.
-void ClipboardMessageFilter::OnFindPboardWriteString(const string16& text) {
+void ClipboardMessageFilter::OnFindPboardWriteString(
+ const base::string16& text) {
if (text.length() <= kMaxFindPboardStringLength) {
NSString* nsText = base::SysUTF16ToNSString(text);
if (nsText) {
diff --git a/content/browser/renderer_host/compositing_iosurface_mac.h b/content/browser/renderer_host/compositing_iosurface_mac.h
index d15f2b8885..06493511b9 100644
--- a/content/browser/renderer_host/compositing_iosurface_mac.h
+++ b/content/browser/renderer_host/compositing_iosurface_mac.h
@@ -69,7 +69,7 @@ class CompositingIOSurfaceMac {
const gfx::Rect& window_rect,
float window_scale_factor,
RenderWidgetHostViewFrameSubscriber* frame_subscriber,
- bool using_core_animation);
+ bool flush_drawable);
// Copy the data of the "live" OpenGL texture referring to this IOSurfaceRef
// into |out|. The copied region is specified with |src_pixel_subrect| and
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index b2e33c8fba..78b23989bd 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -377,12 +377,10 @@ CreateGpuProcessViewContext(
limits.max_transfer_buffer_size = std::min(
3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize);
limits.mapped_memory_reclaim_limit = 2 * 1024 * 1024;
- bool use_echo_for_swap_ack = true;
return make_scoped_ptr(
new WebGraphicsContext3DCommandBufferImpl(surface_id,
url,
gpu_channel_host.get(),
- use_echo_for_swap_ack,
attributes,
false,
limits));
diff --git a/content/browser/renderer_host/database_message_filter.cc b/content/browser/renderer_host/database_message_filter.cc
index d41be65f50..55ea305d6e 100644
--- a/content/browser/renderer_host/database_message_filter.cc
+++ b/content/browser/renderer_host/database_message_filter.cc
@@ -113,13 +113,14 @@ bool DatabaseMessageFilter::OnMessageReceived(
DatabaseMessageFilter::~DatabaseMessageFilter() {
}
-void DatabaseMessageFilter::OnDatabaseOpenFile(const string16& vfs_file_name,
- int desired_flags,
- IPC::Message* reply_msg) {
+void DatabaseMessageFilter::OnDatabaseOpenFile(
+ const base::string16& vfs_file_name,
+ int desired_flags,
+ IPC::Message* reply_msg) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
std::string origin_identifier;
- string16 database_name;
+ base::string16 database_name;
// When in incognito mode, we want to make sure that all DB files are
// removed when the incognito browser context goes away, so we add the
@@ -162,16 +163,18 @@ void DatabaseMessageFilter::OnDatabaseOpenFile(const string16& vfs_file_name,
Send(reply_msg);
}
-void DatabaseMessageFilter::OnDatabaseDeleteFile(const string16& vfs_file_name,
- const bool& sync_dir,
- IPC::Message* reply_msg) {
+void DatabaseMessageFilter::OnDatabaseDeleteFile(
+ const base::string16& vfs_file_name,
+ const bool& sync_dir,
+ IPC::Message* reply_msg) {
DatabaseDeleteFile(vfs_file_name, sync_dir, reply_msg, kNumDeleteRetries);
}
-void DatabaseMessageFilter::DatabaseDeleteFile(const string16& vfs_file_name,
- bool sync_dir,
- IPC::Message* reply_msg,
- int reschedule_count) {
+void DatabaseMessageFilter::DatabaseDeleteFile(
+ const base::string16& vfs_file_name,
+ bool sync_dir,
+ IPC::Message* reply_msg,
+ int reschedule_count) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
// Return an error if the file name is invalid or if the file could not
@@ -183,8 +186,8 @@ void DatabaseMessageFilter::DatabaseDeleteFile(const string16& vfs_file_name,
// In order to delete a journal file in incognito mode, we only need to
// close the open handle to it that's stored in the database tracker.
if (db_tracker_->IsIncognitoProfile()) {
- const string16 wal_suffix(ASCIIToUTF16("-wal"));
- string16 sqlite_suffix;
+ const base::string16 wal_suffix(ASCIIToUTF16("-wal"));
+ base::string16 sqlite_suffix;
// WAL files can be deleted without having previously been opened.
if (!db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name) &&
@@ -215,7 +218,7 @@ void DatabaseMessageFilter::DatabaseDeleteFile(const string16& vfs_file_name,
}
void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
- const string16& vfs_file_name,
+ const base::string16& vfs_file_name,
IPC::Message* reply_msg) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
int32 attributes = -1;
@@ -230,7 +233,7 @@ void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
}
void DatabaseMessageFilter::OnDatabaseGetFileSize(
- const string16& vfs_file_name, IPC::Message* reply_msg) {
+ const base::string16& vfs_file_name, IPC::Message* reply_msg) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
int64 size = 0;
base::FilePath db_file =
@@ -278,8 +281,8 @@ void DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
void DatabaseMessageFilter::OnDatabaseOpened(
const std::string& origin_identifier,
- const string16& database_name,
- const string16& description,
+ const base::string16& database_name,
+ const base::string16& description,
int64 estimated_size) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
@@ -299,7 +302,7 @@ void DatabaseMessageFilter::OnDatabaseOpened(
void DatabaseMessageFilter::OnDatabaseModified(
const std::string& origin_identifier,
- const string16& database_name) {
+ const base::string16& database_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!database_connections_.IsDatabaseOpened(
origin_identifier, database_name)) {
@@ -313,7 +316,7 @@ void DatabaseMessageFilter::OnDatabaseModified(
void DatabaseMessageFilter::OnDatabaseClosed(
const std::string& origin_identifier,
- const string16& database_name) {
+ const base::string16& database_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!database_connections_.IsDatabaseOpened(
origin_identifier, database_name)) {
@@ -328,7 +331,7 @@ void DatabaseMessageFilter::OnDatabaseClosed(
void DatabaseMessageFilter::OnHandleSqliteError(
const std::string& origin_identifier,
- const string16& database_name,
+ const base::string16& database_name,
int error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
@@ -342,7 +345,7 @@ void DatabaseMessageFilter::OnHandleSqliteError(
void DatabaseMessageFilter::OnDatabaseSizeChanged(
const std::string& origin_identifier,
- const string16& database_name,
+ const base::string16& database_name,
int64 database_size) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (database_connections_.IsOriginUsed(origin_identifier)) {
@@ -353,7 +356,7 @@ void DatabaseMessageFilter::OnDatabaseSizeChanged(
void DatabaseMessageFilter::OnDatabaseScheduledForDeletion(
const std::string& origin_identifier,
- const string16& database_name) {
+ const base::string16& database_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name));
}
diff --git a/content/browser/renderer_host/database_message_filter.h b/content/browser/renderer_host/database_message_filter.h
index 9e168c5404..5024335633 100644
--- a/content/browser/renderer_host/database_message_filter.h
+++ b/content/browser/renderer_host/database_message_filter.h
@@ -41,15 +41,15 @@ class DatabaseMessageFilter
void RemoveObserver();
// VFS message handlers (file thread)
- void OnDatabaseOpenFile(const string16& vfs_file_name,
+ void OnDatabaseOpenFile(const base::string16& vfs_file_name,
int desired_flags,
IPC::Message* reply_msg);
- void OnDatabaseDeleteFile(const string16& vfs_file_name,
+ void OnDatabaseDeleteFile(const base::string16& vfs_file_name,
const bool& sync_dir,
IPC::Message* reply_msg);
- void OnDatabaseGetFileAttributes(const string16& vfs_file_name,
+ void OnDatabaseGetFileAttributes(const base::string16& vfs_file_name,
IPC::Message* reply_msg);
- void OnDatabaseGetFileSize(const string16& vfs_file_name,
+ void OnDatabaseGetFileSize(const base::string16& vfs_file_name,
IPC::Message* reply_msg);
// Quota message handler (io thread)
@@ -62,26 +62,26 @@ class DatabaseMessageFilter
// Database tracker message handlers (file thread)
void OnDatabaseOpened(const std::string& origin_identifier,
- const string16& database_name,
- const string16& description,
+ const base::string16& database_name,
+ const base::string16& description,
int64 estimated_size);
void OnDatabaseModified(const std::string& origin_identifier,
- const string16& database_name);
+ const base::string16& database_name);
void OnDatabaseClosed(const std::string& origin_identifier,
- const string16& database_name);
+ const base::string16& database_name);
void OnHandleSqliteError(const std::string& origin_identifier,
- const string16& database_name,
+ const base::string16& database_name,
int error);
// DatabaseTracker::Observer callbacks (file thread)
virtual void OnDatabaseSizeChanged(const std::string& origin_identifier,
- const string16& database_name,
+ const base::string16& database_name,
int64 database_size) OVERRIDE;
virtual void OnDatabaseScheduledForDeletion(
const std::string& origin_identifier,
- const string16& database_name) OVERRIDE;
+ const base::string16& database_name) OVERRIDE;
- void DatabaseDeleteFile(const string16& vfs_file_name,
+ void DatabaseDeleteFile(const base::string16& vfs_file_name,
bool sync_dir,
IPC::Message* reply_msg,
int reschedule_count);
diff --git a/content/browser/renderer_host/file_utilities_message_filter.cc b/content/browser/renderer_host/file_utilities_message_filter.cc
index 65645e014e..5daa6ff221 100644
--- a/content/browser/renderer_host/file_utilities_message_filter.cc
+++ b/content/browser/renderer_host/file_utilities_message_filter.cc
@@ -48,7 +48,7 @@ void FileUtilitiesMessageFilter::OnGetFileInfo(
return;
}
- if (!file_util::GetFileInfo(path, result))
+ if (!base::GetFileInfo(path, result))
*status = base::PLATFORM_FILE_ERROR_FAILED;
}
diff --git a/content/browser/renderer_host/gtk_im_context_wrapper.cc b/content/browser/renderer_host/gtk_im_context_wrapper.cc
index 7ce65585d7..d4b77894f5 100644
--- a/content/browser/renderer_host/gtk_im_context_wrapper.cc
+++ b/content/browser/renderer_host/gtk_im_context_wrapper.cc
@@ -477,7 +477,7 @@ void GtkIMContextWrapper::ConfirmComposition() {
if (host_view_->GetRenderWidgetHost()) {
RenderWidgetHostImpl::From(
host_view_->GetRenderWidgetHost())->ImeConfirmComposition(
- string16(), gfx::Range::InvalidRange(), false);
+ base::string16(), gfx::Range::InvalidRange(), false);
}
// Reset the input method.
@@ -485,7 +485,7 @@ void GtkIMContextWrapper::ConfirmComposition() {
}
}
-void GtkIMContextWrapper::HandleCommit(const string16& text) {
+void GtkIMContextWrapper::HandleCommit(const base::string16& text) {
if (suppress_next_commit_)
return;
diff --git a/content/browser/renderer_host/gtk_im_context_wrapper.h b/content/browser/renderer_host/gtk_im_context_wrapper.h
index 1647df1330..8bd027f0e8 100644
--- a/content/browser/renderer_host/gtk_im_context_wrapper.h
+++ b/content/browser/renderer_host/gtk_im_context_wrapper.h
@@ -75,7 +75,7 @@ class GtkIMContextWrapper {
void ProcessInputMethodResult(const GdkEventKey* event, bool filtered);
// Real code of "commit" signal handler.
- void HandleCommit(const string16& text);
+ void HandleCommit(const base::string16& text);
// Real code of "preedit-start" signal handler.
void HandlePreeditStart();
@@ -180,7 +180,7 @@ class GtkIMContextWrapper {
// Stores a copy of the most recent commit text received by commit signal
// handler.
- string16 commit_text_;
+ base::string16 commit_text_;
// If it's true then the next "commit" signal will be suppressed.
// It's only used to workaround http://crbug.com/50485.
diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc
index a55b823914..5fa9a7e134 100644
--- a/content/browser/renderer_host/image_transport_factory_android.cc
+++ b/content/browser/renderer_host/image_transport_factory_android.cc
@@ -48,7 +48,7 @@ class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid {
}
virtual GLHelper* GetGLHelper() OVERRIDE;
virtual uint32 GetChannelID() OVERRIDE {
- return context_->GetChannelID();
+ return BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
}
private:
@@ -81,12 +81,10 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() {
3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize);
limits.mapped_memory_reclaim_limit =
WebGraphicsContext3DCommandBufferImpl::kNoLimit;
- bool use_echo_for_swap_ack = true;
context_.reset(
new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
url,
gpu_channel_host.get(),
- use_echo_for_swap_ack,
attrs,
false,
limits));
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc
index 9e7fe47c27..92d972f22c 100644
--- a/content/browser/renderer_host/ime_adapter_android.cc
+++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -136,7 +136,7 @@ void ImeAdapterAndroid::SetComposingText(JNIEnv* env, jobject, jstring text,
if (!rwhi)
return;
- string16 text16 = ConvertJavaStringToUTF16(env, text);
+ base::string16 text16 = ConvertJavaStringToUTF16(env, text);
std::vector<blink::WebCompositionUnderline> underlines;
underlines.push_back(
blink::WebCompositionUnderline(0, text16.length(), SK_ColorBLACK,
@@ -155,7 +155,7 @@ void ImeAdapterAndroid::CommitText(JNIEnv* env, jobject, jstring text) {
if (!rwhi)
return;
- string16 text16 = ConvertJavaStringToUTF16(env, text);
+ base::string16 text16 = ConvertJavaStringToUTF16(env, text);
rwhi->ImeConfirmComposition(text16, gfx::Range::InvalidRange(), false);
}
@@ -164,7 +164,8 @@ void ImeAdapterAndroid::FinishComposingText(JNIEnv* env, jobject) {
if (!rwhi)
return;
- rwhi->ImeConfirmComposition(string16(), gfx::Range::InvalidRange(), true);
+ rwhi->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
+ true);
}
void ImeAdapterAndroid::AttachImeAdapter(JNIEnv* env, jobject java_object) {
diff --git a/content/browser/renderer_host/input/gesture_event_filter.h b/content/browser/renderer_host/input/gesture_event_filter.h
index d8ccdf3742..d0517008bf 100644
--- a/content/browser/renderer_host/input/gesture_event_filter.h
+++ b/content/browser/renderer_host/input/gesture_event_filter.h
@@ -93,9 +93,13 @@ class CONTENT_EXPORT GestureEventFilter {
debounce_enabled_ = enabled;
}
+ void set_debounce_interval_time_ms_for_testing(int interval_time_ms) {
+ debounce_interval_time_ms_ = interval_time_ms;
+ }
+
private:
- friend class MockRenderWidgetHost;
friend class GestureEventFilterTest;
+ friend class MockRenderWidgetHost;
// TODO(mohsen): There are a bunch of ShouldForward.../ShouldDiscard...
// methods that are getting confusing. This should be somehow fixed. Maybe
diff --git a/content/browser/renderer_host/input/gesture_event_filter_unittest.cc b/content/browser/renderer_host/input/gesture_event_filter_unittest.cc
index 1ed8d93106..421fd70131 100644
--- a/content/browser/renderer_host/input/gesture_event_filter_unittest.cc
+++ b/content/browser/renderer_host/input/gesture_event_filter_unittest.cc
@@ -10,8 +10,8 @@
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "content/browser/renderer_host/input/gesture_event_filter.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/port/common/input_event_ack_state.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -142,7 +142,7 @@ class GestureEventFilterTest : public testing::Test,
}
void set_debounce_interval_time_ms(int ms) {
- filter()->debounce_interval_time_ms_ = ms;
+ filter()->set_debounce_interval_time_ms_for_testing(ms);
}
void set_synchronous_ack(InputEventAckState ack_result) {
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h
index a346a00f88..2dbb4ed00a 100644
--- a/content/browser/renderer_host/input/input_router.h
+++ b/content/browser/renderer_host/input/input_router.h
@@ -54,6 +54,15 @@ class InputRouter : public IPC::Listener {
// router. When |false|, the caller can forego sending touch events, and
// instead consume them directly.
virtual bool ShouldForwardTouchEvent() const = 0;
+
+ // Allow the router to make more informed input handling decisions based on
+ // the current view.
+ enum ViewFlags {
+ VIEW_FLAGS_NONE = 0,
+ FIXED_PAGE_SCALE = 1 << 0,
+ MOBILE_VIEWPORT = 1 << 1
+ };
+ virtual void OnViewUpdated(int view_flags) = 0;
};
} // namespace content
diff --git a/content/browser/renderer_host/input/immediate_input_router.cc b/content/browser/renderer_host/input/input_router_impl.cc
index 4fa30aae23..59efb11a12 100644
--- a/content/browser/renderer_host/input/immediate_input_router.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/input/immediate_input_router.h"
+#include "content/browser/renderer_host/input/input_router_impl.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/metrics/histogram.h"
+#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/input/gesture_event_filter.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
@@ -15,6 +16,7 @@
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
+#include "content/common/input/touch_action.h"
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
@@ -39,6 +41,21 @@ using blink::WebMouseWheelEvent;
namespace content {
namespace {
+bool GetTouchAckTimeoutDelayMs(size_t* touch_ack_timeout_delay_ms) {
+ CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
+ if (!parsed_command_line->HasSwitch(switches::kTouchAckTimeoutDelayMs))
+ return false;
+
+ std::string timeout_string = parsed_command_line->GetSwitchValueASCII(
+ switches::kTouchAckTimeoutDelayMs);
+ size_t timeout_value;
+ if (!base::StringToSizeT(timeout_string, &timeout_value))
+ return false;
+
+ *touch_ack_timeout_delay_ms = timeout_value;
+ return true;
+}
+
GestureEventWithLatencyInfo MakeGestureEvent(WebInputEvent::Type type,
double timestamp_seconds,
int x,
@@ -63,19 +80,18 @@ const char* GetEventAckName(InputEventAckState ack_result) {
case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED";
case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED";
case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS";
- default:
- DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n";
- break;
+ case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED";
}
+ DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.";
return "";
}
} // namespace
-ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender,
- InputRouterClient* client,
- InputAckHandler* ack_handler,
- int routing_id)
+InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
+ InputRouterClient* client,
+ InputAckHandler* ack_handler,
+ int routing_id)
: sender_(sender),
client_(client),
ack_handler_(ack_handler),
@@ -85,20 +101,25 @@ ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender,
mouse_move_pending_(false),
mouse_wheel_pending_(false),
has_touch_handler_(false),
+ touch_ack_timeout_enabled_(false),
+ touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()),
current_ack_source_(ACK_SOURCE_NONE),
- touch_event_queue_(new TouchEventQueue(this)),
gesture_event_filter_(new GestureEventFilter(this, this)) {
DCHECK(sender);
DCHECK(client);
DCHECK(ack_handler);
+ touch_event_queue_.reset(new TouchEventQueue(this));
+ touch_ack_timeout_enabled_ =
+ GetTouchAckTimeoutDelayMs(&touch_ack_timeout_delay_ms_);
+ touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled_,
+ touch_ack_timeout_delay_ms_);
}
-ImmediateInputRouter::~ImmediateInputRouter() {
-}
+InputRouterImpl::~InputRouterImpl() {}
-void ImmediateInputRouter::Flush() {}
+void InputRouterImpl::Flush() {}
-bool ImmediateInputRouter::SendInput(scoped_ptr<IPC::Message> message) {
+bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) {
DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart);
switch (message->type()) {
// Check for types that require an ACK.
@@ -114,7 +135,7 @@ bool ImmediateInputRouter::SendInput(scoped_ptr<IPC::Message> message) {
}
}
-void ImmediateInputRouter::SendMouseEvent(
+void InputRouterImpl::SendMouseEvent(
const MouseEventWithLatencyInfo& mouse_event) {
// Order is important here; we need to convert all MouseEvents before they
// propagate further, e.g., to the tap suppression controller.
@@ -136,7 +157,7 @@ void ImmediateInputRouter::SendMouseEvent(
SendMouseEventImmediately(mouse_event);
}
-void ImmediateInputRouter::SendWheelEvent(
+void InputRouterImpl::SendWheelEvent(
const MouseWheelEventWithLatencyInfo& wheel_event) {
// If there's already a mouse wheel event waiting to be sent to the renderer,
// add the new deltas to that event. Not doing so (e.g., by dropping the old
@@ -160,10 +181,9 @@ void ImmediateInputRouter::SendWheelEvent(
FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false);
}
-void ImmediateInputRouter::SendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
+void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info,
+ bool is_keyboard_shortcut) {
// Put all WebKeyboardEvent objects in a queue since we can't trust the
// renderer and we need to give something to the HandleKeyboardEvent
// handler.
@@ -176,9 +196,12 @@ void ImmediateInputRouter::SendKeyboardEvent(
FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut);
}
-void ImmediateInputRouter::SendGestureEvent(
+void InputRouterImpl::SendGestureEvent(
const GestureEventWithLatencyInfo& gesture_event) {
- HandleGestureScroll(gesture_event);
+ if (touch_action_filter_.FilterGestureEvent(gesture_event.event))
+ return;
+
+ touch_event_queue_->OnGestureScrollEvent(gesture_event);
if (!IsInOverscrollGesture() &&
!gesture_event_filter_->ShouldForward(gesture_event)) {
@@ -191,14 +214,14 @@ void ImmediateInputRouter::SendGestureEvent(
FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
}
-void ImmediateInputRouter::SendTouchEvent(
+void InputRouterImpl::SendTouchEvent(
const TouchEventWithLatencyInfo& touch_event) {
touch_event_queue_->QueueEvent(touch_event);
}
// Forwards MouseEvent without passing it through
// TouchpadTapSuppressionController.
-void ImmediateInputRouter::SendMouseEventImmediately(
+void InputRouterImpl::SendMouseEventImmediately(
const MouseEventWithLatencyInfo& mouse_event) {
// Avoid spamming the renderer with mouse move events. It is important
// to note that WM_MOUSEMOVE events are anyways synthetic, but since our
@@ -218,25 +241,23 @@ void ImmediateInputRouter::SendMouseEventImmediately(
FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false);
}
-void ImmediateInputRouter::SendTouchEventImmediately(
+void InputRouterImpl::SendTouchEventImmediately(
const TouchEventWithLatencyInfo& touch_event) {
FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false);
}
-void ImmediateInputRouter::SendGestureEventImmediately(
+void InputRouterImpl::SendGestureEventImmediately(
const GestureEventWithLatencyInfo& gesture_event) {
- HandleGestureScroll(gesture_event);
FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
}
-const NativeWebKeyboardEvent*
- ImmediateInputRouter::GetLastKeyboardEvent() const {
+const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
if (key_queue_.empty())
return NULL;
return &key_queue_.front();
}
-bool ImmediateInputRouter::ShouldForwardTouchEvent() const {
+bool InputRouterImpl::ShouldForwardTouchEvent() const {
// Always send a touch event if the renderer has a touch-event handler. It is
// possible that a renderer stops listening to touch-events while there are
// still events in the touch-queue. In such cases, the new events should still
@@ -244,15 +265,25 @@ bool ImmediateInputRouter::ShouldForwardTouchEvent() const {
return has_touch_handler_ || !touch_event_queue_->empty();
}
-bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) {
+void InputRouterImpl::OnViewUpdated(int view_flags) {
+ bool fixed_page_scale = (view_flags & FIXED_PAGE_SCALE) != 0;
+ bool mobile_viewport = (view_flags & MOBILE_VIEWPORT) != 0;
+ touch_event_queue_->SetAckTimeoutEnabled(
+ touch_ack_timeout_enabled_ && !(fixed_page_scale || mobile_viewport),
+ touch_ack_timeout_delay_ms_);
+}
+
+bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
bool message_is_ok = true;
- IPC_BEGIN_MESSAGE_MAP_EX(ImmediateInputRouter, message, message_is_ok)
+ IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok)
IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
OnHasTouchEventHandlers)
+ IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction,
+ OnSetTouchAction)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -262,20 +293,19 @@ bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) {
return handled;
}
-void ImmediateInputRouter::OnTouchEventAck(
- const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) {
+void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+ InputEventAckState ack_result) {
ack_handler_->OnTouchEventAck(event, ack_result);
}
-void ImmediateInputRouter::OnGestureEventAck(
+void InputRouterImpl::OnGestureEventAck(
const GestureEventWithLatencyInfo& event,
InputEventAckState ack_result) {
ProcessAckForOverscroll(event.event, ack_result);
ack_handler_->OnGestureEventAck(event, ack_result);
}
-bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
+bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) {
DCHECK(message->type() == InputMsg_SelectRange::ID);
if (select_range_pending_) {
next_selection_range_ = message.Pass();
@@ -286,7 +316,7 @@ bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
return Send(message.release());
}
-bool ImmediateInputRouter::SendMoveCaret(scoped_ptr<IPC::Message> message) {
+bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) {
DCHECK(message->type() == InputMsg_MoveCaret::ID);
if (move_caret_pending_) {
next_move_caret_ = message.Pass();
@@ -297,16 +327,18 @@ bool ImmediateInputRouter::SendMoveCaret(scoped_ptr<IPC::Message> message) {
return Send(message.release());
}
-bool ImmediateInputRouter::Send(IPC::Message* message) {
+bool InputRouterImpl::Send(IPC::Message* message) {
return sender_->Send(message);
}
-void ImmediateInputRouter::FilterAndSendWebInputEvent(
+void InputRouterImpl::FilterAndSendWebInputEvent(
const WebInputEvent& input_event,
const ui::LatencyInfo& latency_info,
bool is_keyboard_shortcut) {
- TRACE_EVENT1("input", "ImmediateInputRouter::FilterAndSendWebInputEvent",
- "type", WebInputEventTraits::GetName(input_event.type));
+ TRACE_EVENT1("input",
+ "InputRouterImpl::FilterAndSendWebInputEvent",
+ "type",
+ WebInputEventTraits::GetName(input_event.type));
// Transmit any pending wheel events on a non-wheel event. This ensures that
// final PhaseEnded wheel event is received, which is necessary to terminate
@@ -327,9 +359,9 @@ void ImmediateInputRouter::FilterAndSendWebInputEvent(
OfferToHandlers(input_event, latency_info, is_keyboard_shortcut);
}
-void ImmediateInputRouter::OfferToHandlers(const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
+void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event,
+ const ui::LatencyInfo& latency_info,
+ bool is_keyboard_shortcut) {
if (OfferToOverscrollController(input_event, latency_info))
return;
@@ -347,7 +379,7 @@ void ImmediateInputRouter::OfferToHandlers(const WebInputEvent& input_event,
}
}
-bool ImmediateInputRouter::OfferToOverscrollController(
+bool InputRouterImpl::OfferToOverscrollController(
const WebInputEvent& input_event,
const ui::LatencyInfo& latency_info) {
OverscrollController* controller = client_->GetOverscrollController();
@@ -382,8 +414,8 @@ bool ImmediateInputRouter::OfferToOverscrollController(
return consumed;
}
-bool ImmediateInputRouter::OfferToClient(const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info) {
+bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event,
+ const ui::LatencyInfo& latency_info) {
bool consumed = false;
InputEventAckState filter_ack =
@@ -408,7 +440,7 @@ bool ImmediateInputRouter::OfferToClient(const WebInputEvent& input_event,
return consumed;
}
-bool ImmediateInputRouter::OfferToRenderer(const WebInputEvent& input_event,
+bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event,
const ui::LatencyInfo& latency_info,
bool is_keyboard_shortcut) {
input_event_start_time_ = TimeTicks::Now();
@@ -420,10 +452,9 @@ bool ImmediateInputRouter::OfferToRenderer(const WebInputEvent& input_event,
return false;
}
-void ImmediateInputRouter::OnInputEventAck(
- WebInputEvent::Type event_type,
- InputEventAckState ack_result,
- const ui::LatencyInfo& latency_info) {
+void InputRouterImpl::OnInputEventAck(WebInputEvent::Type event_type,
+ InputEventAckState ack_result,
+ const ui::LatencyInfo& latency_info) {
// Log the time delta for processing an input event.
TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
@@ -451,19 +482,19 @@ void ImmediateInputRouter::OnInputEventAck(
Details<int>(&type));
}
-void ImmediateInputRouter::OnMsgMoveCaretAck() {
+void InputRouterImpl::OnMsgMoveCaretAck() {
move_caret_pending_ = false;
if (next_move_caret_)
SendMoveCaret(next_move_caret_.Pass());
}
-void ImmediateInputRouter::OnSelectRangeAck() {
+void InputRouterImpl::OnSelectRangeAck() {
select_range_pending_ = false;
if (next_selection_range_)
SendSelectRange(next_selection_range_.Pass());
}
-void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) {
+void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
if (has_touch_handler_ == has_handlers)
return;
has_touch_handler_ = has_handlers;
@@ -472,12 +503,20 @@ void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) {
client_->OnHasTouchEventHandlers(has_handlers);
}
-void ImmediateInputRouter::ProcessInputEventAck(
+void InputRouterImpl::OnSetTouchAction(
+ content::TouchAction touch_action) {
+ // Synthetic touchstart events should get filtered out in RenderWidget.
+ DCHECK(touch_event_queue_->IsPendingAckTouchStart());
+
+ touch_action_filter_.OnSetTouchAction(touch_action);
+}
+
+void InputRouterImpl::ProcessInputEventAck(
WebInputEvent::Type event_type,
InputEventAckState ack_result,
const ui::LatencyInfo& latency_info,
AckSource ack_source) {
- TRACE_EVENT2("input", "ImmediateInputRouter::ProcessInputEventAck",
+ TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck",
"type", WebInputEventTraits::GetName(event_type),
"ack", GetEventAckName(ack_result));
@@ -506,9 +545,8 @@ void ImmediateInputRouter::ProcessInputEventAck(
}
}
-void ImmediateInputRouter::ProcessKeyboardAck(
- blink::WebInputEvent::Type type,
- InputEventAckState ack_result) {
+void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type,
+ InputEventAckState ack_result) {
if (key_queue_.empty()) {
ack_handler_->OnUnexpectedEventAck(InputAckHandler::UNEXPECTED_ACK);
} else if (key_queue_.front().type != type) {
@@ -521,15 +559,15 @@ void ImmediateInputRouter::ProcessKeyboardAck(
key_queue_.pop_front();
ack_handler_->OnKeyboardEventAck(front_item, ack_result);
- // WARNING: This ImmediateInputRouter can be deallocated at this point
+ // WARNING: This InputRouterImpl can be deallocated at this point
// (i.e. in the case of Ctrl+W, where the call to
- // HandleKeyboardEvent destroys this ImmediateInputRouter).
+ // HandleKeyboardEvent destroys this InputRouterImpl).
// TODO(jdduke): crbug.com/274029 - Make ack-triggered shutdown async.
}
}
-void ImmediateInputRouter::ProcessMouseAck(blink::WebInputEvent::Type type,
- InputEventAckState ack_result) {
+void InputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type,
+ InputEventAckState ack_result) {
if (type != WebInputEvent::MouseMove)
return;
@@ -543,8 +581,8 @@ void ImmediateInputRouter::ProcessMouseAck(blink::WebInputEvent::Type type,
}
}
-void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result,
- const ui::LatencyInfo& latency) {
+void InputRouterImpl::ProcessWheelAck(InputEventAckState ack_result,
+ const ui::LatencyInfo& latency) {
ProcessAckForOverscroll(current_wheel_event_.event, ack_result);
// TODO(miletus): Add renderer side latency to each uncoalesced mouse
@@ -564,9 +602,9 @@ void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result,
}
}
-void ImmediateInputRouter::ProcessGestureAck(WebInputEvent::Type type,
- InputEventAckState ack_result,
- const ui::LatencyInfo& latency) {
+void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type,
+ InputEventAckState ack_result,
+ const ui::LatencyInfo& latency) {
// If |ack_result| originated from the overscroll controller, only
// feed |gesture_event_filter_| the ack if it was expecting one.
if (current_ack_source_ == OVERSCROLL_CONTROLLER &&
@@ -578,16 +616,15 @@ void ImmediateInputRouter::ProcessGestureAck(WebInputEvent::Type type,
gesture_event_filter_->ProcessGestureAck(ack_result, type, latency);
}
-void ImmediateInputRouter::ProcessTouchAck(
+void InputRouterImpl::ProcessTouchAck(
InputEventAckState ack_result,
const ui::LatencyInfo& latency) {
// |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
touch_event_queue_->ProcessTouchAck(ack_result, latency);
}
-void ImmediateInputRouter::ProcessAckForOverscroll(
- const WebInputEvent& event,
- InputEventAckState ack_result) {
+void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event,
+ InputEventAckState ack_result) {
// Acks sent from the overscroll controller need not be fed back into the
// overscroll controller.
if (current_ack_source_ == OVERSCROLL_CONTROLLER)
@@ -601,12 +638,7 @@ void ImmediateInputRouter::ProcessAckForOverscroll(
event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result));
}
-void ImmediateInputRouter::HandleGestureScroll(
- const GestureEventWithLatencyInfo& gesture_event) {
- touch_event_queue_->OnGestureScrollEvent(gesture_event);
-}
-
-void ImmediateInputRouter::SimulateTouchGestureWithMouse(
+void InputRouterImpl::SimulateTouchGestureWithMouse(
const MouseEventWithLatencyInfo& event) {
const WebMouseEvent& mouse_event = event.event;
int x = mouse_event.x, y = mouse_event.y;
@@ -686,7 +718,7 @@ void ImmediateInputRouter::SimulateTouchGestureWithMouse(
}
}
-bool ImmediateInputRouter::IsInOverscrollGesture() const {
+bool InputRouterImpl::IsInOverscrollGesture() const {
OverscrollController* controller = client_->GetOverscrollController();
return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
}
diff --git a/content/browser/renderer_host/input/immediate_input_router.h b/content/browser/renderer_host/input/input_router_impl.h
index 56e4987c5f..e12b7510cc 100644
--- a/content/browser/renderer_host/input/immediate_input_router.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
#include <queue>
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/input/gesture_event_filter.h"
#include "content/browser/renderer_host/input/input_router.h"
+#include "content/browser/renderer_host/input/touch_action_filter.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -31,19 +32,18 @@ class InputRouterClient;
class OverscrollController;
class RenderWidgetHostImpl;
-// A default implementation for browser input event routing. Input commands are
-// forwarded to the renderer immediately upon receipt.
-class CONTENT_EXPORT ImmediateInputRouter
+// A default implementation for browser input event routing.
+class CONTENT_EXPORT InputRouterImpl
: public NON_EXPORTED_BASE(InputRouter),
public NON_EXPORTED_BASE(GestureEventFilterClient),
public NON_EXPORTED_BASE(TouchEventQueueClient),
public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
public:
- ImmediateInputRouter(IPC::Sender* sender,
- InputRouterClient* client,
- InputAckHandler* ack_handler,
- int routing_id);
- virtual ~ImmediateInputRouter();
+ InputRouterImpl(IPC::Sender* sender,
+ InputRouterClient* client,
+ InputAckHandler* ack_handler,
+ int routing_id);
+ virtual ~InputRouterImpl();
// InputRouter
virtual void Flush() OVERRIDE;
@@ -62,12 +62,13 @@ class CONTENT_EXPORT ImmediateInputRouter
const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE;
virtual bool ShouldForwardTouchEvent() const OVERRIDE;
+ virtual void OnViewUpdated(int view_flags) OVERRIDE;
// IPC::Listener
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
- friend class ImmediateInputRouterTest;
+ friend class InputRouterImplTest;
friend class MockRenderWidgetHost;
// TouchpadTapSuppressionControllerClient
@@ -123,6 +124,7 @@ private:
void OnMsgMoveCaretAck();
void OnSelectRangeAck();
void OnHasTouchEventHandlers(bool has_handlers);
+ void OnSetTouchAction(content::TouchAction touch_action);
// Indicates the source of an ack provided to |ProcessInputEventAck()|.
// The source is tracked by |current_ack_source_|, which aids in ack routing.
@@ -168,8 +170,6 @@ private:
void ProcessAckForOverscroll(const blink::WebInputEvent& event,
InputEventAckState ack_result);
- void HandleGestureScroll(const GestureEventWithLatencyInfo& gesture_event);
-
void SimulateTouchGestureWithMouse(
const MouseEventWithLatencyInfo& mouse_event);
@@ -235,16 +235,21 @@ private:
// not sent to the renderer.
bool has_touch_handler_;
+ // Whether touch ack timeout handling has been enabled via the command line.
+ bool touch_ack_timeout_enabled_;
+ size_t touch_ack_timeout_delay_ms_;
+
// The source of the ack within the scope of |ProcessInputEventAck()|.
// Defaults to ACK_SOURCE_NONE.
AckSource current_ack_source_;
scoped_ptr<TouchEventQueue> touch_event_queue_;
scoped_ptr<GestureEventFilter> gesture_event_filter_;
+ TouchActionFilter touch_action_filter_;
- DISALLOW_COPY_AND_ASSIGN(ImmediateInputRouter);
+ DISALLOW_COPY_AND_ASSIGN(InputRouterImpl);
};
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_IMPL_H_
diff --git a/content/browser/renderer_host/input/immediate_input_router_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index dfd1ee026b..ba94e8057b 100644
--- a/content/browser/renderer_host/input/immediate_input_router_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -3,18 +3,21 @@
// found in the LICENSE file.
#include "base/basictypes.h"
+#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/renderer_host/input/gesture_event_filter.h"
-#include "content/browser/renderer_host/input/immediate_input_router.h"
#include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/input/input_router_unittest.h"
+#include "content/browser/renderer_host/input/input_router_impl.h"
+#include "content/browser/renderer_host/input/mock_input_ack_handler.h"
#include "content/browser/renderer_host/input/mock_input_router_client.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,6 +30,7 @@
using base::TimeDelta;
using blink::WebGestureEvent;
+using blink::WebKeyboardEvent;
using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
@@ -103,23 +107,149 @@ bool EventListIsSubset(const ScopedVector<ui::TouchEvent>& subset,
} // namespace
-class ImmediateInputRouterTest : public InputRouterTest {
+class InputRouterImplTest : public testing::Test {
public:
- ImmediateInputRouterTest() {}
- virtual ~ImmediateInputRouterTest() {}
+ InputRouterImplTest() {}
+ virtual ~InputRouterImplTest() {}
protected:
- // InputRouterTest
- virtual scoped_ptr<InputRouter> CreateInputRouter(RenderProcessHost* process,
- InputRouterClient* client,
- InputAckHandler* handler,
- int routing_id) OVERRIDE {
- ImmediateInputRouter* ir =
- new ImmediateInputRouter(process, client, handler, routing_id);
- ir->gesture_event_filter_->set_debounce_enabled_for_testing(false);
- return scoped_ptr<InputRouter>(ir);
+ // testing::Test
+ virtual void SetUp() OVERRIDE {
+ browser_context_.reset(new TestBrowserContext());
+ process_.reset(new MockRenderProcessHost(browser_context_.get()));
+ client_.reset(new MockInputRouterClient());
+ ack_handler_.reset(new MockInputAckHandler());
+ input_router_.reset(new InputRouterImpl(
+ process_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
+ input_router_->gesture_event_filter_->set_debounce_enabled_for_testing(
+ false);
+ client_->set_input_router(input_router());
+ ack_handler_->set_input_router(input_router());
}
+ virtual void TearDown() OVERRIDE {
+ // Process all pending tasks to avoid leaks.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ input_router_.reset();
+ client_.reset();
+ process_.reset();
+ browser_context_.reset();
+ }
+
+ void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
+ WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
+ NativeWebKeyboardEvent native_event;
+ memcpy(&native_event, &event, sizeof(event));
+ input_router_->SendKeyboardEvent(
+ native_event,
+ ui::LatencyInfo(),
+ is_shortcut);
+ }
+
+ void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
+ input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
+ SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
+ ui::LatencyInfo()));
+ }
+
+ void SimulateMouseMove(int x, int y, int modifiers) {
+ input_router_->SendMouseEvent(MouseEventWithLatencyInfo(
+ SyntheticWebMouseEventBuilder::Build(
+ WebInputEvent::MouseMove, x, y, modifiers),
+ ui::LatencyInfo()));
+ }
+
+ void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
+ input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
+ SyntheticWebMouseWheelEventBuilder::Build(phase), ui::LatencyInfo()));
+ }
+
+ void SimulateGestureEvent(const WebGestureEvent& gesture) {
+ input_router_->SendGestureEvent(
+ GestureEventWithLatencyInfo(gesture, ui::LatencyInfo()));
+ }
+
+ void SimulateGestureEvent(WebInputEvent::Type type,
+ WebGestureEvent::SourceDevice sourceDevice) {
+ SimulateGestureEvent(
+ SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
+ }
+
+ void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) {
+ SimulateGestureEvent(
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers));
+ }
+
+ void SimulateGesturePinchUpdateEvent(float scale,
+ float anchorX,
+ float anchorY,
+ int modifiers) {
+ SimulateGestureEvent(
+ SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
+ anchorX,
+ anchorY,
+ modifiers));
+ }
+
+ void SimulateGestureFlingStartEvent(
+ float velocityX,
+ float velocityY,
+ WebGestureEvent::SourceDevice sourceDevice) {
+ SimulateGestureEvent(
+ SyntheticWebGestureEventBuilder::BuildFling(velocityX,
+ velocityY,
+ sourceDevice));
+ }
+
+ void SimulateTouchEvent(WebInputEvent::Type type) {
+ touch_event_.ResetPoints();
+ int index = PressTouchPoint(0, 0);
+ switch (type) {
+ case WebInputEvent::TouchStart:
+ // Already handled by |PressTouchPoint()|.
+ break;
+ case WebInputEvent::TouchMove:
+ MoveTouchPoint(index, 5, 5);
+ break;
+ case WebInputEvent::TouchEnd:
+ ReleaseTouchPoint(index);
+ break;
+ case WebInputEvent::TouchCancel:
+ CancelTouchPoint(index);
+ break;
+ default:
+ FAIL() << "Invalid touch event type.";
+ break;
+ }
+ SendTouchEvent();
+ }
+
+ void SetTouchTimestamp(base::TimeDelta timestamp) {
+ touch_event_.SetTimestamp(timestamp);
+ }
+
+ void SendTouchEvent() {
+ input_router_->SendTouchEvent(
+ TouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo()));
+ touch_event_.ResetPoints();
+ }
+
+ int PressTouchPoint(int x, int y) {
+ return touch_event_.PressPoint(x, y);
+ }
+
+ void MoveTouchPoint(int index, int x, int y) {
+ touch_event_.MovePoint(index, x, y);
+ }
+
+ void ReleaseTouchPoint(int index) {
+ touch_event_.ReleasePoint(index);
+ }
+
+ void CancelTouchPoint(int index) {
+ touch_event_.CancelPoint(index);
+ }
void SendInputEventACK(blink::WebInputEvent::Type type,
InputEventAckState ack_result) {
scoped_ptr<IPC::Message> response(
@@ -128,26 +258,37 @@ class ImmediateInputRouterTest : public InputRouterTest {
input_router_->OnMessageReceived(*response);
}
- ImmediateInputRouter* input_router() const {
- return static_cast<ImmediateInputRouter*>(input_router_.get());
- }
-
- bool no_touch_to_renderer() {
- return input_router()->touch_event_queue_->no_touch_to_renderer();
+ InputRouterImpl* input_router() const {
+ return input_router_.get();
}
bool TouchEventQueueEmpty() const {
return input_router()->touch_event_queue_->empty();
}
+ bool TouchEventTimeoutEnabled() const {
+ return input_router()->touch_event_queue_->ack_timeout_enabled();
+ }
+
size_t GetSentMessageCountAndResetSink() {
size_t count = process_->sink().message_count();
process_->sink().ClearMessages();
return count;
}
+
+ scoped_ptr<MockRenderProcessHost> process_;
+ scoped_ptr<MockInputRouterClient> client_;
+ scoped_ptr<MockInputAckHandler> ack_handler_;
+ scoped_ptr<InputRouterImpl> input_router_;
+
+ private:
+ base::MessageLoopForUI message_loop_;
+ SyntheticWebTouchEvent touch_event_;
+
+ scoped_ptr<TestBrowserContext> browser_context_;
};
-TEST_F(ImmediateInputRouterTest, CoalescesRangeSelection) {
+TEST_F(InputRouterImplTest, CoalescesRangeSelection) {
input_router_->SendInput(scoped_ptr<IPC::Message>(
new InputMsg_SelectRange(0, gfx::Point(1, 2), gfx::Point(3, 4))));
ExpectIPCMessageWithArg2<InputMsg_SelectRange>(
@@ -186,7 +327,7 @@ TEST_F(ImmediateInputRouterTest, CoalescesRangeSelection) {
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
}
-TEST_F(ImmediateInputRouterTest, CoalescesCaretMove) {
+TEST_F(InputRouterImplTest, CoalescesCaretMove) {
input_router_->SendInput(
scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(1, 2))));
ExpectIPCMessageWithArg1<InputMsg_MoveCaret>(
@@ -221,7 +362,7 @@ TEST_F(ImmediateInputRouterTest, CoalescesCaretMove) {
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
}
-TEST_F(ImmediateInputRouterTest, HandledInputEvent) {
+TEST_F(InputRouterImplTest, HandledInputEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED);
// Simulate a keyboard event.
@@ -238,7 +379,7 @@ TEST_F(ImmediateInputRouterTest, HandledInputEvent) {
ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
}
-TEST_F(ImmediateInputRouterTest, ClientCanceledKeyboardEvent) {
+TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
// Simulate a keyboard event that has no consumer.
@@ -258,7 +399,7 @@ TEST_F(ImmediateInputRouterTest, ClientCanceledKeyboardEvent) {
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
}
-TEST_F(ImmediateInputRouterTest, ShortcutKeyboardEvent) {
+TEST_F(InputRouterImplTest, ShortcutKeyboardEvent) {
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, true);
EXPECT_TRUE(GetIsShortcutFromHandleInputEventMessage(
process_->sink().GetMessageAt(0)));
@@ -270,7 +411,7 @@ TEST_F(ImmediateInputRouterTest, ShortcutKeyboardEvent) {
process_->sink().GetMessageAt(0)));
}
-TEST_F(ImmediateInputRouterTest, NoncorrespondingKeyEvents) {
+TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) {
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
SendInputEventACK(WebInputEvent::KeyUp,
@@ -280,7 +421,7 @@ TEST_F(ImmediateInputRouterTest, NoncorrespondingKeyEvents) {
// Tests ported from RenderWidgetHostTest --------------------------------------
-TEST_F(ImmediateInputRouterTest, HandleKeyEventsWeSent) {
+TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
// Simulate a keyboard event.
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
ASSERT_TRUE(input_router_->GetLastKeyboardEvent());
@@ -300,7 +441,7 @@ TEST_F(ImmediateInputRouterTest, HandleKeyEventsWeSent) {
ack_handler_->acked_keyboard_event().type);
}
-TEST_F(ImmediateInputRouterTest, IgnoreKeyEventsWeDidntSend) {
+TEST_F(InputRouterImplTest, IgnoreKeyEventsWeDidntSend) {
// Send a simulated, unrequested key response. We should ignore this.
SendInputEventACK(WebInputEvent::RawKeyDown,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
@@ -308,7 +449,7 @@ TEST_F(ImmediateInputRouterTest, IgnoreKeyEventsWeDidntSend) {
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
}
-TEST_F(ImmediateInputRouterTest, CoalescesWheelEvents) {
+TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
// Simulate wheel events.
SimulateWheelEvent(0, -5, 0, false); // sent directly
SimulateWheelEvent(0, -10, 0, false); // enqueued
@@ -320,7 +461,7 @@ TEST_F(ImmediateInputRouterTest, CoalescesWheelEvents) {
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- // Check that the ACK sends the second message via ImmediateInputForwarder
+ // Check that the ACK sends the second message immediately.
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
// The coalesced events can queue up a delayed ack
@@ -349,7 +490,7 @@ TEST_F(ImmediateInputRouterTest, CoalescesWheelEvents) {
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
}
-TEST_F(ImmediateInputRouterTest,
+TEST_F(InputRouterImplTest,
CoalescesWheelEventsQueuedPhaseEndIsNotDropped) {
// Send an initial gesture begin and ACK it.
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -388,7 +529,7 @@ TEST_F(ImmediateInputRouterTest,
}
// Tests that touch-events are queued properly.
-TEST_F(ImmediateInputRouterTest, TouchEventQueue) {
+TEST_F(InputRouterImplTest, TouchEventQueue) {
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
@@ -422,7 +563,7 @@ TEST_F(ImmediateInputRouterTest, TouchEventQueue) {
// Tests that the touch-queue is emptied if a page stops listening for touch
// events.
-TEST_F(ImmediateInputRouterTest, TouchEventQueueFlush) {
+TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
EXPECT_TRUE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
@@ -449,7 +590,7 @@ TEST_F(ImmediateInputRouterTest, TouchEventQueueFlush) {
#if defined(OS_WIN) || defined(USE_AURA)
// Tests that the acked events have correct state. (ui::Events are used only on
// windows and aura)
-TEST_F(ImmediateInputRouterTest, AckedTouchEventState) {
+TEST_F(InputRouterImplTest, AckedTouchEventState) {
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
@@ -533,7 +674,7 @@ TEST_F(ImmediateInputRouterTest, AckedTouchEventState) {
}
#endif // defined(OS_WIN) || defined(USE_AURA)
-TEST_F(ImmediateInputRouterTest, UnhandledWheelEvent) {
+TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
// Simulate wheel events.
SimulateWheelEvent(0, -5, 0, false); // sent directly
SimulateWheelEvent(0, -10, 0, false); // enqueued
@@ -561,7 +702,7 @@ TEST_F(ImmediateInputRouterTest, UnhandledWheelEvent) {
EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5);
}
-TEST_F(ImmediateInputRouterTest, TouchTypesIgnoringAck) {
+TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
int start_type = static_cast<int>(WebInputEvent::TouchStart);
int end_type = static_cast<int>(WebInputEvent::TouchCancel);
for (int i = start_type; i <= end_type; ++i) {
@@ -588,7 +729,7 @@ TEST_F(ImmediateInputRouterTest, TouchTypesIgnoringAck) {
}
}
-TEST_F(ImmediateInputRouterTest, GestureTypesIgnoringAck) {
+TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
int start_type = static_cast<int>(WebInputEvent::GestureScrollBegin);
int end_type = static_cast<int>(WebInputEvent::GesturePinchUpdate);
for (int i = start_type; i <= end_type; ++i) {
@@ -607,7 +748,7 @@ TEST_F(ImmediateInputRouterTest, GestureTypesIgnoringAck) {
// Test that GestureShowPress, GestureTapDown and GestureTapCancel events don't
// wait for ACKs.
-TEST_F(ImmediateInputRouterTest, GestureTypesIgnoringAckInterleaved) {
+TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
// Interleave a few events that do and do not ignore acks, ensuring that
// ack-ignoring events aren't dispatched until all prior events which observe
// their ack disposition have been dispatched.
@@ -680,7 +821,7 @@ TEST_F(ImmediateInputRouterTest, GestureTypesIgnoringAckInterleaved) {
// Test that GestureShowPress events don't get out of order due to
// ignoring their acks.
-TEST_F(ImmediateInputRouterTest, GestureShowPressIsInOrder) {
+TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
SimulateGestureEvent(WebInputEvent::GestureTap,
WebGestureEvent::Touchscreen);
@@ -711,4 +852,31 @@ TEST_F(ImmediateInputRouterTest, GestureShowPressIsInOrder) {
EXPECT_EQ(3U, ack_handler_->GetAndResetAckCount());
}
+// Test that touch ack timeout behavior is properly configured via the command
+// line, and toggled by the view update flags.
+TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
+ CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kTouchAckTimeoutDelayMs, "5");
+ TearDown();
+ SetUp();
+ ASSERT_TRUE(TouchEventTimeoutEnabled());
+
+ // A fixed page scale or mobile viewport should disable the touch timeout.
+ input_router()->OnViewUpdated(InputRouter::FIXED_PAGE_SCALE);
+ EXPECT_FALSE(TouchEventTimeoutEnabled());
+
+ input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
+ EXPECT_TRUE(TouchEventTimeoutEnabled());
+
+ input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT);
+ EXPECT_FALSE(TouchEventTimeoutEnabled());
+
+ input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT |
+ InputRouter::FIXED_PAGE_SCALE);
+ EXPECT_FALSE(TouchEventTimeoutEnabled());
+
+ input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
+ EXPECT_TRUE(TouchEventTimeoutEnabled());
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/input_router_unittest.cc b/content/browser/renderer_host/input/input_router_unittest.cc
deleted file mode 100644
index b1181eed9b..0000000000
--- a/content/browser/renderer_host/input/input_router_unittest.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/input/input_router_unittest.h"
-
-#include "content/browser/renderer_host/input/input_router.h"
-#include "content/common/input_messages.h"
-
-using blink::WebGestureEvent;
-using blink::WebInputEvent;
-using blink::WebMouseEvent;
-using blink::WebMouseWheelEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-namespace content {
-
-InputRouterTest::InputRouterTest() {}
-InputRouterTest::~InputRouterTest() {}
-
-void InputRouterTest::SetUp() {
- browser_context_.reset(new TestBrowserContext());
- process_.reset(new MockRenderProcessHost(browser_context_.get()));
- client_.reset(new MockInputRouterClient());
- ack_handler_.reset(new MockInputAckHandler());
- input_router_ = CreateInputRouter(process_.get(),
- client_.get(),
- ack_handler_.get(),
- MSG_ROUTING_NONE);
- client_->set_input_router(input_router_.get());
- ack_handler_->set_input_router(input_router_.get());
-}
-
-void InputRouterTest::TearDown() {
- // Process all pending tasks to avoid InputRouterTest::leaks.
- base::MessageLoop::current()->RunUntilIdle();
-
- input_router_.reset();
- client_.reset();
- process_.reset();
- browser_context_.reset();
-}
-
-void InputRouterTest::SimulateKeyboardEvent(WebInputEvent::Type type,
- bool is_shortcut) {
- input_router_->SendKeyboardEvent(
- SyntheticWebKeyboardEventBuilder::Build(type),
- ui::LatencyInfo(),
- is_shortcut);
-}
-
-void InputRouterTest::SimulateWheelEvent(float dX,
- float dY,
- int modifiers,
- bool precise) {
- input_router_->SendWheelEvent(
- MouseWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
- ui::LatencyInfo()));
-}
-
-void InputRouterTest::SimulateMouseMove(int x, int y, int modifiers) {
- input_router_->SendMouseEvent(
- MouseEventWithLatencyInfo(SyntheticWebMouseEventBuilder::Build(
- WebInputEvent::MouseMove, x, y, modifiers),
- ui::LatencyInfo()));
-}
-
-void InputRouterTest::SimulateWheelEventWithPhase(
- WebMouseWheelEvent::Phase phase) {
- input_router_->SendWheelEvent(
- MouseWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(phase), ui::LatencyInfo()));
-}
-
-void InputRouterTest::SimulateGestureEvent(
- const WebGestureEvent& gesture) {
- GestureEventWithLatencyInfo gesture_with_latency(gesture, ui::LatencyInfo());
- input_router_->SendGestureEvent(gesture_with_latency);
-}
-
-void InputRouterTest::SimulateGestureEvent(
- WebInputEvent::Type type,
- WebGestureEvent::SourceDevice sourceDevice) {
- SimulateGestureEvent(
- SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
-}
-
-void InputRouterTest::SimulateGestureScrollUpdateEvent(float dX,
- float dY,
- int modifiers) {
- SimulateGestureEvent(
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers));
-}
-
-void InputRouterTest::SimulateGesturePinchUpdateEvent(float scale,
- float anchorX,
- float anchorY,
- int modifiers) {
- SimulateGestureEvent(
- SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
- anchorX,
- anchorY,
- modifiers));
-}
-
-void InputRouterTest::SimulateGestureFlingStartEvent(
- float velocityX,
- float velocityY,
- WebGestureEvent::SourceDevice sourceDevice) {
- SimulateGestureEvent(
- SyntheticWebGestureEventBuilder::BuildFling(velocityX,
- velocityY,
- sourceDevice));
-}
-
-void InputRouterTest::SimulateTouchEvent(WebInputEvent::Type type) {
- touch_event_.ResetPoints();
- int index = PressTouchPoint(0, 0);
- switch (type) {
- case WebInputEvent::TouchStart:
- // Already handled by |PressTouchPoint()|.
- break;
- case WebInputEvent::TouchMove:
- MoveTouchPoint(index, 5, 5);
- break;
- case WebInputEvent::TouchEnd:
- ReleaseTouchPoint(index);
- break;
- case WebInputEvent::TouchCancel:
- CancelTouchPoint(index);
- break;
- default:
- FAIL() << "Invalid touch event type.";
- break;
- }
- SendTouchEvent();
-}
-
-void InputRouterTest::SetTouchTimestamp(base::TimeDelta timestamp) {
- touch_event_.SetTimestamp(timestamp);
-}
-
-void InputRouterTest::SendTouchEvent() {
- input_router_->SendTouchEvent(
- TouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo()));
- touch_event_.ResetPoints();
-}
-
-int InputRouterTest::PressTouchPoint(int x, int y) {
- return touch_event_.PressPoint(x, y);
-}
-
-void InputRouterTest::MoveTouchPoint(int index, int x, int y) {
- touch_event_.MovePoint(index, x, y);
-}
-
-void InputRouterTest::ReleaseTouchPoint(int index) {
- touch_event_.ReleasePoint(index);
-}
-
-void InputRouterTest::CancelTouchPoint(int index) {
- touch_event_.CancelPoint(index);
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/input/input_router_unittest.h b/content/browser/renderer_host/input/input_router_unittest.h
deleted file mode 100644
index d9a6775456..0000000000
--- a/content/browser/renderer_host/input/input_router_unittest.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_UNITTEST_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_UNITTEST_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/input/mock_input_ack_handler.h"
-#include "content/browser/renderer_host/input/mock_input_router_client.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
-#include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/test_browser_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-namespace content {
-
-class InputRouter;
-class MockInputRouterClient;
-
-class InputRouterTest : public testing::Test {
- public:
- InputRouterTest();
- virtual ~InputRouterTest();
-
- protected:
- // Called on SetUp.
- virtual scoped_ptr<InputRouter> CreateInputRouter(RenderProcessHost* process,
- InputRouterClient* client,
- InputAckHandler* handler,
- int routing_id) = 0;
-
- // testing::Test
- virtual void SetUp() OVERRIDE;
- virtual void TearDown() OVERRIDE;
-
- void SendInputEventACK(blink::WebInputEvent::Type type,
- InputEventAckState ack_result);
- void SimulateKeyboardEvent(blink::WebInputEvent::Type type,
- bool is_shortcut);
- void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise);
- void SimulateMouseMove(int x, int y, int modifiers);
- void SimulateWheelEventWithPhase(blink::WebMouseWheelEvent::Phase phase);
- void SimulateGestureEvent(const blink::WebGestureEvent& event);
- void SimulateGestureEvent(blink::WebInputEvent::Type type,
- blink::WebGestureEvent::SourceDevice sourceDevice);
- void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers);
- void SimulateGesturePinchUpdateEvent(float scale,
- float anchorX,
- float anchorY,
- int modifiers);
- void SimulateGestureFlingStartEvent(
- float velocityX,
- float velocityY,
- blink::WebGestureEvent::SourceDevice sourceDevice);
- void SimulateTouchEvent(blink::WebInputEvent::Type type);
- void SetTouchTimestamp(base::TimeDelta timestamp);
-
- // Sends a touch event (irrespective of whether the page has a touch-event
- // handler or not).
- void SendTouchEvent();
-
- int PressTouchPoint(int x, int y);
- void MoveTouchPoint(int index, int x, int y);
- void ReleaseTouchPoint(int index);
- void CancelTouchPoint(int index);
-
- scoped_ptr<MockRenderProcessHost> process_;
- scoped_ptr<MockInputRouterClient> client_;
- scoped_ptr<MockInputAckHandler> ack_handler_;
- scoped_ptr<InputRouter> input_router_;
-
- private:
- base::MessageLoopForUI message_loop_;
- SyntheticWebTouchEvent touch_event_;
-
- scoped_ptr<TestBrowserContext> browser_context_;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_MOCK_INPUT_ROUTER_UNITTEST_H_
diff --git a/content/browser/renderer_host/input/synthetic_gesture.cc b/content/browser/renderer_host/input/synthetic_gesture.cc
index 9b57168dcd..8b2b3bedbe 100644
--- a/content/browser/renderer_host/input/synthetic_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture.cc
@@ -4,9 +4,11 @@
#include "content/browser/renderer_host/input/synthetic_gesture.h"
+#include "base/logging.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/input/synthetic_pinch_gesture.h"
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
namespace content {
namespace {
@@ -33,6 +35,9 @@ scoped_ptr<SyntheticGesture> SyntheticGesture::Create(
case SyntheticGestureParams::PINCH_GESTURE:
return CreateGesture<SyntheticPinchGesture,
SyntheticPinchGestureParams>(gesture_params);
+ case SyntheticGestureParams::TAP_GESTURE:
+ return CreateGesture<SyntheticTapGesture,
+ SyntheticTapGestureParams>(gesture_params);
}
NOTREACHED() << "Invalid synthetic gesture type";
return scoped_ptr<SyntheticGesture>();
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
index baefa695d1..f449e5774c 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -9,15 +9,21 @@
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/input/synthetic_pinch_gesture.h"
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/input/input_event.h"
+#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
+#include "content/common/input/synthetic_tap_gesture_params.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/point.h"
#include "ui/gfx/point_f.h"
+#include "ui/gfx/vector2d.h"
+#include "ui/gfx/vector2d_f.h"
namespace content {
@@ -25,6 +31,7 @@ namespace {
const int kFlushInputRateInMs = 16;
const int kPointerAssumedStoppedTimeMs = 43;
+const int kTouchSlopInDips = 7;
class MockSyntheticGesture : public SyntheticGesture {
public:
@@ -100,6 +107,10 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget {
pointer_assumed_stopped_time_ms_ = time_ms;
}
+ virtual int GetTouchSlopInDips() const OVERRIDE {
+ return kTouchSlopInDips;
+ }
+
int num_success() const { return num_success_; }
int num_failure() const { return num_failure_; }
@@ -115,9 +126,22 @@ class MockSyntheticGestureTarget : public SyntheticGestureTarget {
int pointer_assumed_stopped_time_ms_;
};
-class MockSyntheticSmoothScrollMouseTarget : public MockSyntheticGestureTarget {
+class MockSyntheticSmoothScrollGestureTarget
+ : public MockSyntheticGestureTarget {
public:
- MockSyntheticSmoothScrollMouseTarget() : scroll_distance_(0) {}
+ MockSyntheticSmoothScrollGestureTarget() {}
+ virtual ~MockSyntheticSmoothScrollGestureTarget() {}
+
+ gfx::Vector2dF scroll_distance() const { return scroll_distance_; }
+
+ protected:
+ gfx::Vector2dF scroll_distance_;
+};
+
+class MockSyntheticSmoothScrollMouseTarget
+ : public MockSyntheticSmoothScrollGestureTarget {
+ public:
+ MockSyntheticSmoothScrollMouseTarget() {}
virtual ~MockSyntheticSmoothScrollMouseTarget() {}
virtual void DispatchInputEventToPlatform(const InputEvent& event) OVERRIDE {
@@ -125,20 +149,16 @@ class MockSyntheticSmoothScrollMouseTarget : public MockSyntheticGestureTarget {
ASSERT_EQ(web_event->type, blink::WebInputEvent::MouseWheel);
const blink::WebMouseWheelEvent* mouse_wheel_event =
static_cast<const blink::WebMouseWheelEvent*>(web_event);
- ASSERT_EQ(mouse_wheel_event->deltaX, 0);
- scroll_distance_ -= mouse_wheel_event->deltaY;
+ scroll_distance_ -= gfx::Vector2dF(mouse_wheel_event->deltaX,
+ mouse_wheel_event->deltaY);
}
-
- float scroll_distance() const { return scroll_distance_; }
-
- private:
- float scroll_distance_;
};
-class MockSyntheticSmoothScrollTouchTarget : public MockSyntheticGestureTarget {
+class MockSyntheticSmoothScrollTouchTarget
+ : public MockSyntheticSmoothScrollGestureTarget {
public:
MockSyntheticSmoothScrollTouchTarget()
- : scroll_distance_(0), anchor_y_(0), started_(false) {}
+ : started_(false) {}
virtual ~MockSyntheticSmoothScrollTouchTarget() {}
virtual void DispatchInputEventToPlatform(const InputEvent& event) OVERRIDE {
@@ -150,7 +170,8 @@ class MockSyntheticSmoothScrollTouchTarget : public MockSyntheticGestureTarget {
if (!started_) {
ASSERT_EQ(touch_event->type, blink::WebInputEvent::TouchStart);
- anchor_y_ = touch_event->touches[0].position.y;
+ anchor_.SetPoint(touch_event->touches[0].position.x,
+ touch_event->touches[0].position.y);
started_ = true;
} else {
ASSERT_NE(touch_event->type, blink::WebInputEvent::TouchStart);
@@ -158,15 +179,14 @@ class MockSyntheticSmoothScrollTouchTarget : public MockSyntheticGestureTarget {
// Ignore move events.
if (touch_event->type == blink::WebInputEvent::TouchEnd)
- scroll_distance_ = anchor_y_ - touch_event->touches[0].position.y;
+ scroll_distance_ =
+ anchor_ - gfx::PointF(touch_event->touches[0].position.x,
+ touch_event->touches[0].position.y);
}
}
- float scroll_distance() const { return scroll_distance_; }
-
- private:
- float scroll_distance_;
- float anchor_y_;
+ protected:
+ gfx::Point anchor_;
bool started_;
};
@@ -244,6 +264,88 @@ class MockSyntheticPinchTouchTarget : public MockSyntheticGestureTarget {
bool started_;
};
+class MockSyntheticTapGestureTarget : public MockSyntheticGestureTarget {
+ public:
+ MockSyntheticTapGestureTarget() : state_(NOT_STARTED) {}
+ virtual ~MockSyntheticTapGestureTarget() {}
+
+ bool GestureFinished() const { return state_ == FINISHED; }
+ gfx::Point position() const { return position_; }
+
+ protected:
+ enum GestureState {
+ NOT_STARTED,
+ STARTED,
+ FINISHED
+ };
+
+ gfx::Point position_;
+ GestureState state_;
+};
+
+class MockSyntheticTapTouchTarget : public MockSyntheticTapGestureTarget {
+ public:
+ MockSyntheticTapTouchTarget() {}
+ virtual ~MockSyntheticTapTouchTarget() {}
+
+ virtual void DispatchInputEventToPlatform(const InputEvent& event) OVERRIDE {
+ const blink::WebInputEvent* web_event = event.web_event.get();
+ ASSERT_TRUE(blink::WebInputEvent::isTouchEventType(web_event->type));
+ const blink::WebTouchEvent* touch_event =
+ static_cast<const blink::WebTouchEvent*>(web_event);
+ ASSERT_EQ(touch_event->touchesLength, (unsigned int)1);
+
+ switch (state_) {
+ case NOT_STARTED:
+ EXPECT_EQ(touch_event->type, blink::WebInputEvent::TouchStart);
+ position_ = gfx::Point(touch_event->touches[0].position);
+ state_ = STARTED;
+ break;
+ case STARTED:
+ EXPECT_EQ(touch_event->type, blink::WebInputEvent::TouchEnd);
+ EXPECT_EQ(position_, gfx::Point(touch_event->touches[0].position));
+ state_ = FINISHED;
+ break;
+ case FINISHED:
+ EXPECT_FALSE(true);
+ break;
+ }
+ }
+};
+
+class MockSyntheticTapMouseTarget : public MockSyntheticTapGestureTarget {
+ public:
+ MockSyntheticTapMouseTarget() {}
+ virtual ~MockSyntheticTapMouseTarget() {}
+
+ virtual void DispatchInputEventToPlatform(const InputEvent& event) OVERRIDE {
+ const blink::WebInputEvent* web_event = event.web_event.get();
+ ASSERT_TRUE(blink::WebInputEvent::isMouseEventType(web_event->type));
+ const blink::WebMouseEvent* mouse_event =
+ static_cast<const blink::WebMouseEvent*>(web_event);
+
+ switch (state_) {
+ case NOT_STARTED:
+ EXPECT_EQ(mouse_event->type, blink::WebInputEvent::MouseDown);
+ EXPECT_EQ(mouse_event->button, blink::WebMouseEvent::ButtonLeft);
+ EXPECT_EQ(mouse_event->clickCount, 1);
+ position_ = gfx::Point(mouse_event->x, mouse_event->y);
+ state_ = STARTED;
+ break;
+ case STARTED:
+ EXPECT_EQ(mouse_event->type, blink::WebInputEvent::MouseUp);
+ EXPECT_EQ(mouse_event->button, blink::WebMouseEvent::ButtonLeft);
+ EXPECT_EQ(mouse_event->clickCount, 1);
+ EXPECT_EQ(position_, gfx::Point(mouse_event->x, mouse_event->y));
+ state_ = FINISHED;
+ break;
+ case FINISHED:
+ EXPECT_FALSE(true);
+ break;
+ }
+ }
+};
+
class SyntheticGestureControllerTest : public testing::Test {
public:
SyntheticGestureControllerTest() {}
@@ -359,23 +461,105 @@ TEST_F(SyntheticGestureControllerTest, TwoGesturesInFlight) {
EXPECT_EQ(0, target_->num_failure());
}
-TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouch) {
+gfx::Vector2d AddTouchSlopToVector(const gfx::Vector2d& vector,
+ SyntheticGestureTarget* target) {
+ const int kTouchSlop = target->GetTouchSlopInDips();
+
+ int x = vector.x();
+ if (x > 0)
+ x += kTouchSlop;
+ else if (x < 0)
+ x -= kTouchSlop;
+
+ int y = vector.y();
+ if (y > 0)
+ y += kTouchSlop;
+ else if (y < 0)
+ y -= kTouchSlop;
+
+ return gfx::Vector2d(x, y);
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchVertical) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.distance = gfx::Vector2d(0, 123);
+ params.anchor.SetPoint(89, 32);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(AddTouchSlopToVector(params.distance, target_),
+ smooth_scroll_target->scroll_distance());
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchHorizontal) {
CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
SyntheticSmoothScrollGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
- params.distance = 123;
+ params.distance = gfx::Vector2d(-234, 0);
+ params.anchor.SetPoint(12, -23);
scoped_ptr<SyntheticSmoothScrollGesture> gesture(
new SyntheticSmoothScrollGesture(params));
controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
FlushInputUntilComplete();
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_FLOAT_EQ(params.distance,
- static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
- ->scroll_distance());
+ EXPECT_EQ(AddTouchSlopToVector(params.distance, target_),
+ smooth_scroll_target->scroll_distance());
+}
+
+void CheckIsWithinRange(float scroll_distance,
+ int target_distance,
+ SyntheticGestureTarget* target) {
+ if (target_distance > 0) {
+ EXPECT_LE(target_distance, scroll_distance);
+ EXPECT_LE(scroll_distance, target_distance + target->GetTouchSlopInDips());
+ } else {
+ EXPECT_GE(target_distance, scroll_distance);
+ EXPECT_GE(scroll_distance, target_distance - target->GetTouchSlopInDips());
+ }
+}
+
+void CheckScrollDistanceIsWithinRange(const gfx::Vector2dF& scroll_distance,
+ const gfx::Vector2d& target_distance,
+ SyntheticGestureTarget* target) {
+ CheckIsWithinRange(scroll_distance.x(), target_distance.x(), target);
+ CheckIsWithinRange(scroll_distance.y(), target_distance.y(), target);
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchDiagonal) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.distance = gfx::Vector2d(413, -83);
+ params.anchor.SetPoint(0, 7);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ CheckScrollDistanceIsWithinRange(
+ smooth_scroll_target->scroll_distance(), params.distance, target_);
}
TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchLongStop) {
@@ -386,7 +570,9 @@ TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchLongStop) {
// gesture is active.
SyntheticSmoothScrollGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
- params.distance = 21;
+ params.distance = gfx::Vector2d(21, -12);
+ params.prevent_fling = true;
+ params.anchor.SetPoint(-98, -23);
target_->set_pointer_assumed_stopped_time_ms(543);
@@ -395,31 +581,121 @@ TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchLongStop) {
controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
FlushInputUntilComplete();
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_FLOAT_EQ(params.distance,
- static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
- ->scroll_distance());
+ CheckScrollDistanceIsWithinRange(
+ smooth_scroll_target->scroll_distance(), params.distance, target_);
EXPECT_GE(GetTotalTime(), target_->PointerAssumedStoppedTime());
}
-TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouse) {
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchFling) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
+
+ // Create a smooth scroll with a short distance and set the pointer assumed
+ // stopped time high. Disable 'prevent_fling' and check that the gesture
+ // finishes without waiting before it stops.
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.distance = gfx::Vector2d(-43, 19);
+ params.prevent_fling = false;
+ params.anchor.SetPoint(-89, 78);
+
+ target_->set_pointer_assumed_stopped_time_ms(543);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ CheckScrollDistanceIsWithinRange(
+ smooth_scroll_target->scroll_distance(), params.distance, target_);
+ EXPECT_LE(GetTotalTime(), target_->PointerAssumedStoppedTime());
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureTouchZeroDistance) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollTouchTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.distance = gfx::Vector2d(0, 0);
+ params.anchor.SetPoint(-32, 43);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(gfx::Vector2dF(0, 0), smooth_scroll_target->scroll_distance());
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseVertical) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params.distance = gfx::Vector2d(0, -234);
+ params.anchor.SetPoint(432, 89);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseHorizontal) {
CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
SyntheticSmoothScrollGestureParams params;
params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
- params.distance = -234;
+ params.distance = gfx::Vector2d(345, 0);
+ params.anchor.SetPoint(90, 12);
scoped_ptr<SyntheticSmoothScrollGesture> gesture(
new SyntheticSmoothScrollGesture(params));
controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
FlushInputUntilComplete();
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_FLOAT_EQ(params.distance,
- static_cast<MockSyntheticSmoothScrollTouchTarget*>(target_)
- ->scroll_distance());
+ EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
+}
+
+TEST_F(SyntheticGestureControllerTest, SmoothScrollGestureMouseDiagonal) {
+ CreateControllerAndTarget<MockSyntheticSmoothScrollMouseTarget>();
+
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params.distance = gfx::Vector2d(-194, 303);
+ params.anchor.SetPoint(90, 12);
+
+ scoped_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticSmoothScrollGestureTarget* smooth_scroll_target =
+ static_cast<MockSyntheticSmoothScrollGestureTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(params.distance, smooth_scroll_target->scroll_distance());
}
TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
@@ -429,19 +705,20 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomIn) {
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.zoom_in = true;
params.total_num_pixels_covered = 345;
+ params.anchor.SetPoint(54, 89);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
FlushInputUntilComplete();
+ MockSyntheticPinchTouchTarget* pinch_target =
+ static_cast<MockSyntheticPinchTouchTarget*>(target_);
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_EQ(
- static_cast<MockSyntheticPinchTouchTarget*>(target_)->zoom_direction(),
- MockSyntheticPinchTouchTarget::ZOOM_IN);
- EXPECT_FLOAT_EQ(params.total_num_pixels_covered,
- static_cast<MockSyntheticPinchTouchTarget*>(target_)
- ->total_num_pixels_covered());
+ EXPECT_EQ(pinch_target->zoom_direction(),
+ MockSyntheticPinchTouchTarget::ZOOM_IN);
+ EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
+ pinch_target->total_num_pixels_covered());
}
TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
@@ -451,19 +728,85 @@ TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZoomOut) {
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.zoom_in = false;
params.total_num_pixels_covered = 456;
+ params.anchor.SetPoint(-12, 93);
scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
FlushInputUntilComplete();
+ MockSyntheticPinchTouchTarget* pinch_target =
+ static_cast<MockSyntheticPinchTouchTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(pinch_target->zoom_direction(),
+ MockSyntheticPinchTouchTarget::ZOOM_OUT);
+ EXPECT_EQ(params.total_num_pixels_covered + 2 * target_->GetTouchSlopInDips(),
+ pinch_target->total_num_pixels_covered());
+}
+
+TEST_F(SyntheticGestureControllerTest, PinchGestureTouchZeroPixelsCovered) {
+ CreateControllerAndTarget<MockSyntheticPinchTouchTarget>();
+
+ SyntheticPinchGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.zoom_in = true;
+ params.total_num_pixels_covered = 0;
+
+ scoped_ptr<SyntheticPinchGesture> gesture(new SyntheticPinchGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticPinchTouchTarget* pinch_target =
+ static_cast<MockSyntheticPinchTouchTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_EQ(pinch_target->zoom_direction(),
+ MockSyntheticPinchTouchTarget::ZOOM_DIRECTION_UNKNOWN);
+ EXPECT_EQ(0, pinch_target->total_num_pixels_covered());
+}
+
+TEST_F(SyntheticGestureControllerTest, TapGestureTouch) {
+ CreateControllerAndTarget<MockSyntheticTapTouchTarget>();
+
+ SyntheticTapGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.duration_ms = 123;
+ params.position.SetPoint(87, -124);
+
+ scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticTapTouchTarget* tap_target =
+ static_cast<MockSyntheticTapTouchTarget*>(target_);
+ EXPECT_EQ(1, target_->num_success());
+ EXPECT_EQ(0, target_->num_failure());
+ EXPECT_TRUE(tap_target->GestureFinished());
+ EXPECT_EQ(tap_target->position(), params.position);
+ EXPECT_GE(GetTotalTime(),
+ base::TimeDelta::FromMilliseconds(params.duration_ms));
+}
+
+TEST_F(SyntheticGestureControllerTest, TapGestureMouse) {
+ CreateControllerAndTarget<MockSyntheticTapMouseTarget>();
+
+ SyntheticTapGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params.duration_ms = 79;
+ params.position.SetPoint(98, 123);
+
+ scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
+ controller_->QueueSyntheticGesture(gesture.PassAs<SyntheticGesture>());
+ FlushInputUntilComplete();
+
+ MockSyntheticTapMouseTarget* tap_target =
+ static_cast<MockSyntheticTapMouseTarget*>(target_);
EXPECT_EQ(1, target_->num_success());
EXPECT_EQ(0, target_->num_failure());
- EXPECT_EQ(
- static_cast<MockSyntheticPinchTouchTarget*>(target_)->zoom_direction(),
- MockSyntheticPinchTouchTarget::ZOOM_OUT);
- EXPECT_FLOAT_EQ(params.total_num_pixels_covered,
- static_cast<MockSyntheticPinchTouchTarget*>(target_)
- ->total_num_pixels_covered());
+ EXPECT_TRUE(tap_target->GestureFinished());
+ EXPECT_EQ(tap_target->position(), params.position);
+ EXPECT_GE(GetTotalTime(),
+ base::TimeDelta::FromMilliseconds(params.duration_ms));
}
} // namespace
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target.h b/content/browser/renderer_host/input/synthetic_gesture_target.h
index 5b31b0294f..01487fc277 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target.h
@@ -44,6 +44,10 @@ class CONTENT_EXPORT SyntheticGestureTarget {
// After how much time of inaction does the target assume that a pointer has
// stopped moving.
virtual base::TimeDelta PointerAssumedStoppedTime() const = 0;
+
+ // Returns the maximum number of DIPs a touch pointer can move without being
+ // considered moving by the platform.
+ virtual int GetTouchSlopInDips() const = 0;
};
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
index acaee85dd9..cf5181ab93 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.cc
@@ -5,8 +5,11 @@
#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "content/browser/android/content_view_core_impl.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "jni/TouchEventSynthesizer_jni.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/android/view_configuration.h"
+#include "ui/gfx/screen.h"
using blink::WebTouchEvent;
@@ -80,4 +83,10 @@ bool SyntheticGestureTargetAndroid::SupportsSyntheticGestureSourceType(
return gesture_source_type == SyntheticGestureParams::TOUCH_INPUT;
}
+int SyntheticGestureTargetAndroid::GetTouchSlopInDips() const {
+ float device_scale_factor =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
+ return gfx::ViewConfiguration::GetTouchSlopInPixels() / device_scale_factor;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
index d31516e98b..b8c5a5d814 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_android.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
@@ -33,6 +33,8 @@ class SyntheticGestureTargetAndroid : public SyntheticGestureTargetBase {
SyntheticGestureParams::GestureSourceType gesture_source_type) const
OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
private:
// Enum values below need to be kept in sync with TouchEventSynthesizer.java
enum Action {
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
index 1d5c6a8d29..9e103137ad 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -11,6 +11,7 @@
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/events/gestures/gesture_configuration.h"
using blink::WebTouchEvent;
using blink::WebMouseWheelEvent;
@@ -70,4 +71,10 @@ bool SyntheticGestureTargetAura::SupportsSyntheticGestureSourceType(
gesture_source_type == SyntheticGestureParams::MOUSE_INPUT;
}
+int SyntheticGestureTargetAura::GetTouchSlopInDips() const {
+ // - 1 because Aura considers a pointer to be moving if it has moved at least
+ // 'max_touch_move_in_pixels_for_click' pixels.
+ return ui::GestureConfiguration::max_touch_move_in_pixels_for_click() - 1;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.h b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
index 69837de83a..5a4ab9cbfe 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.h
@@ -30,6 +30,8 @@ class SyntheticGestureTargetAura : public SyntheticGestureTargetBase {
SyntheticGestureParams::GestureSourceType gesture_source_type) const
OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(SyntheticGestureTargetAura);
};
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
index bc6dc8f2f4..0938eebb64 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.cc
@@ -25,6 +25,11 @@ namespace {
// fling on Android.
const int kPointerAssumedStoppedTimeMs = 50;
+// SyntheticGestureTargetBase passes input events straight on to the renderer
+// without going through a gesture recognition framework. There is thus no touch
+// slop.
+const int kTouchSlopInDips = 0;
+
} // namespace
SyntheticGestureTargetBase::SyntheticGestureTargetBase(
@@ -110,4 +115,8 @@ base::TimeDelta SyntheticGestureTargetBase::PointerAssumedStoppedTime()
return base::TimeDelta::FromMilliseconds(kPointerAssumedStoppedTimeMs);
}
+int SyntheticGestureTargetBase::GetTouchSlopInDips() const {
+ return kTouchSlopInDips;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_base.h b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
index 711c0c3a55..efb8d76b57 100644
--- a/content/browser/renderer_host/input/synthetic_gesture_target_base.h
+++ b/content/browser/renderer_host/input/synthetic_gesture_target_base.h
@@ -55,8 +55,10 @@ class SyntheticGestureTargetBase : public SyntheticGestureTarget {
virtual base::TimeDelta PointerAssumedStoppedTime() const OVERRIDE;
+ virtual int GetTouchSlopInDips() const OVERRIDE;
+
protected:
- RenderWidgetHostImpl* render_widget_host() { return host_; }
+ RenderWidgetHostImpl* render_widget_host() const { return host_; }
private:
RenderWidgetHostImpl* host_;
diff --git a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
index 7700b6d59a..dfe5cf474e 100644
--- a/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_pinch_gesture.cc
@@ -6,77 +6,92 @@
#include <cmath>
+#include "base/logging.h"
#include "content/common/input/input_event.h"
#include "ui/events/latency_info.h"
namespace content {
-namespace {
-
-// TODO(dominikg): Use touch slop to compute this value.
-const float kMinPointerDistance = 40.0f;
-
-}
SyntheticPinchGesture::SyntheticPinchGesture(
const SyntheticPinchGestureParams& params)
- : params_(params), started_(false) {
+ : params_(params),
+ current_y_0_(0.0f),
+ current_y_1_(0.0f),
+ target_y_0_(0.0f),
+ target_y_1_(0.0f),
+ gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
+ state_(SETUP) {
DCHECK_GE(params_.total_num_pixels_covered, 0);
-
- float inner_distance_to_anchor = kMinPointerDistance / 2.0f;
- float outer_distance_to_anchor =
- inner_distance_to_anchor + params_.total_num_pixels_covered / 2.0f;
-
- // Move pointers away from each other to zoom in
- // or towards each other to zoom out.
- if (params_.zoom_in) {
- current_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
- current_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
- target_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
- target_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
- } else {
- current_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
- current_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
- target_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
- target_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
- }
}
SyntheticPinchGesture::~SyntheticPinchGesture() {}
SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents(
const base::TimeDelta& interval, SyntheticGestureTarget* target) {
+ if (state_ == SETUP) {
+ gesture_source_type_ = params_.gesture_source_type;
+ if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
+ gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
- SyntheticGestureParams::GestureSourceType source =
- params_.gesture_source_type;
- if (source == SyntheticGestureParams::DEFAULT_INPUT)
- source = target->GetDefaultSyntheticGestureSourceType();
+ if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_))
+ return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM;
- if (!target->SupportsSyntheticGestureSourceType(source))
- return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM;
+ state_ = STARTED;
+ }
- if (source == SyntheticGestureParams::TOUCH_INPUT)
- return ForwardTouchInputEvents(interval, target);
+ DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
+ if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT)
+ ForwardTouchInputEvents(interval, target);
else
return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
+
+ return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED
+ : SyntheticGesture::GESTURE_RUNNING;
}
-SyntheticGesture::Result SyntheticPinchGesture::ForwardTouchInputEvents(
+void SyntheticPinchGesture::ForwardTouchInputEvents(
const base::TimeDelta& interval, SyntheticGestureTarget* target) {
- if (HasFinished())
- return SyntheticGesture::GESTURE_FINISHED;
-
- if (!started_) {
- touch_event_.PressPoint(params_.anchor.x(), current_y_0_);
- touch_event_.PressPoint(params_.anchor.x(), current_y_1_);
- ForwardTouchEvent(target);
- started_ = true;
+ switch (state_) {
+ case STARTED:
+ // Check for an early finish.
+ if (params_.total_num_pixels_covered == 0) {
+ state_ = DONE;
+ break;
+ }
+ SetupCoordinates(target);
+ PressTouchPoints(target);
+ state_ = MOVING;
+ break;
+ case MOVING:
+ UpdateTouchPoints(interval);
+ MoveTouchPoints(target);
+ if (HasReachedTarget()) {
+ ReleaseTouchPoints(target);
+ state_ = DONE;
+ }
+ break;
+ case SETUP:
+ NOTREACHED() << "State SETUP invalid for synthetic pinch.";
+ case DONE:
+ NOTREACHED() << "State DONE invalid for synthetic pinch.";
}
+}
+void SyntheticPinchGesture::UpdateTouchPoints(base::TimeDelta interval) {
// Compute the delta for the first pointer. The other one moves exactly
// the same but in the opposite direction.
float delta = GetDeltaForPointer0(interval);
current_y_0_ += delta;
current_y_1_ -= delta;
+}
+
+void SyntheticPinchGesture::PressTouchPoints(SyntheticGestureTarget* target) {
+ touch_event_.PressPoint(params_.anchor.x(), current_y_0_);
+ touch_event_.PressPoint(params_.anchor.x(), current_y_1_);
+ ForwardTouchEvent(target);
+}
+
+void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target) {
// The current pointer positions are stored as float but the pointer
// coordinates of the input event are integers. Floor both positions so that
// in case of an odd distance one of the pointers (the one whose position goes
@@ -85,22 +100,43 @@ SyntheticGesture::Result SyntheticPinchGesture::ForwardTouchInputEvents(
touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0_));
touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1_));
ForwardTouchEvent(target);
+}
- if (HasFinished()) {
- touch_event_.ReleasePoint(0);
- touch_event_.ReleasePoint(1);
- ForwardTouchEvent(target);
- return SyntheticGesture::GESTURE_FINISHED;
- }
-
- return SyntheticGesture::GESTURE_RUNNING;
+void SyntheticPinchGesture::ReleaseTouchPoints(SyntheticGestureTarget* target) {
+ touch_event_.ReleasePoint(0);
+ touch_event_.ReleasePoint(1);
+ ForwardTouchEvent(target);
}
-void SyntheticPinchGesture::ForwardTouchEvent(SyntheticGestureTarget* target) {
+
+void SyntheticPinchGesture::ForwardTouchEvent(SyntheticGestureTarget* target)
+ const {
target->DispatchInputEventToPlatform(
InputEvent(touch_event_, ui::LatencyInfo(), false));
}
+void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) {
+ const float kTouchSlopInDips = target->GetTouchSlopInDips();
+ float inner_distance_to_anchor = 2 * kTouchSlopInDips;
+ float outer_distance_to_anchor = inner_distance_to_anchor +
+ params_.total_num_pixels_covered / 2.0f +
+ kTouchSlopInDips;
+
+ // Move pointers away from each other to zoom in
+ // or towards each other to zoom out.
+ if (params_.zoom_in) {
+ current_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
+ current_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
+ target_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
+ target_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
+ } else {
+ current_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
+ current_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
+ target_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
+ target_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
+ }
+}
+
float SyntheticPinchGesture::GetDeltaForPointer0(
const base::TimeDelta& interval) const {
float total_abs_delta =
@@ -123,7 +159,7 @@ float SyntheticPinchGesture::ComputeAbsoluteRemainingDistance() const {
return 2 * distance_0;
}
-bool SyntheticPinchGesture::HasFinished() const {
+bool SyntheticPinchGesture::HasReachedTarget() const {
return ComputeAbsoluteRemainingDistance() == 0;
}
diff --git a/content/browser/renderer_host/input/synthetic_pinch_gesture.h b/content/browser/renderer_host/input/synthetic_pinch_gesture.h
index e8cdebfc6e..97405ce126 100644
--- a/content/browser/renderer_host/input/synthetic_pinch_gesture.h
+++ b/content/browser/renderer_host/input/synthetic_pinch_gesture.h
@@ -7,9 +7,9 @@
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
#include "content/common/content_export.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
namespace content {
@@ -23,23 +23,36 @@ class CONTENT_EXPORT SyntheticPinchGesture : public SyntheticGesture {
const base::TimeDelta& interval, SyntheticGestureTarget* target) OVERRIDE;
private:
+ enum GestureState {
+ SETUP,
+ STARTED,
+ MOVING,
+ DONE
+ };
+
+ void ForwardTouchInputEvents(
+ const base::TimeDelta& interval, SyntheticGestureTarget* target);
+
+ void UpdateTouchPoints(base::TimeDelta interval);
+ void PressTouchPoints(SyntheticGestureTarget* target);
+ void MoveTouchPoints(SyntheticGestureTarget* target);
+ void ReleaseTouchPoints(SyntheticGestureTarget* target);
+ void ForwardTouchEvent(SyntheticGestureTarget* target) const;
+
+ void SetupCoordinates(SyntheticGestureTarget* target);
+ float GetDeltaForPointer0(const base::TimeDelta& interval) const;
+ float ComputeAbsoluteRemainingDistance() const;
+ bool HasReachedTarget() const;
+
SyntheticPinchGestureParams params_;
float current_y_0_;
float current_y_1_;
float target_y_0_;
float target_y_1_;
- bool started_;
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ GestureState state_;
SyntheticWebTouchEvent touch_event_;
- SyntheticGesture::Result ForwardTouchInputEvents(
- const base::TimeDelta& interval, SyntheticGestureTarget* target);
-
- void ForwardTouchEvent(SyntheticGestureTarget* target);
-
- float GetDeltaForPointer0(const base::TimeDelta& interval) const;
- float ComputeAbsoluteRemainingDistance() const;
- bool HasFinished() const;
-
DISALLOW_COPY_AND_ASSIGN(SyntheticPinchGesture);
};
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
index 84d4a1812a..b2fb4bb7eb 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
@@ -4,17 +4,31 @@
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
-#include <cmath>
-
+#include "base/logging.h"
#include "content/common/input/input_event.h"
#include "ui/events/latency_info.h"
+#include "ui/gfx/point_f.h"
namespace content {
+namespace {
+
+gfx::Vector2d FloorTowardZero(const gfx::Vector2dF& vector) {
+ int x = vector.x() > 0 ? floor(vector.x()) : ceil(vector.x());
+ int y = vector.y() > 0 ? floor(vector.y()) : ceil(vector.y());
+ return gfx::Vector2d(x, y);
+}
+
+gfx::Vector2d CeilFromZero(const gfx::Vector2dF& vector) {
+ int x = vector.x() > 0 ? ceil(vector.x()) : floor(vector.x());
+ int y = vector.y() > 0 ? ceil(vector.y()) : floor(vector.y());
+ return gfx::Vector2d(x, y);
+}
+
+} // namespace
SyntheticSmoothScrollGesture::SyntheticSmoothScrollGesture(
const SyntheticSmoothScrollGestureParams& params)
: params_(params),
- current_y_(params_.anchor.y()),
gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
state_(SETUP) {}
@@ -50,30 +64,34 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents(
switch (state_) {
case STARTED:
// Check for an early finish.
- if (HasScrolledEntireDistance()) {
+ if (params_.distance.IsZero()) {
state_ = DONE;
break;
}
- touch_event_.PressPoint(params_.anchor.x(), current_y_);
- ForwardTouchEvent(target);
+ AddTouchSlopToDistance(target);
+ PressTouchPoint(target);
state_ = MOVING;
break;
case MOVING:
- current_y_ += GetPositionDelta(interval);
- touch_event_.MovePoint(0, params_.anchor.x(), current_y_);
- ForwardTouchEvent(target);
+ total_delta_ += GetPositionDelta(interval);
+ MoveTouchPoint(target);
- if (HasScrolledEntireDistance())
- state_ = STOPPING;
+ if (HasScrolledEntireDistance()) {
+ if (params_.prevent_fling) {
+ state_ = STOPPING;
+ } else {
+ ReleaseTouchPoint(target);
+ state_ = DONE;
+ }
+ }
break;
case STOPPING:
total_stopping_wait_time_ += interval;
if (total_stopping_wait_time_ >= target->PointerAssumedStoppedTime()) {
// Send one last move event, but don't change the location. Without this
// we'd still sometimes cause a fling on Android.
- ForwardTouchEvent(target);
- touch_event_.ReleasePoint(0);
- ForwardTouchEvent(target);
+ MoveTouchPoint(target);
+ ReleaseTouchPoint(target);
state_ = DONE;
}
break;
@@ -91,7 +109,7 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents(
switch (state_) {
case STARTED:
// Check for an early finish.
- if (HasScrolledEntireDistance()) {
+ if (params_.distance.IsZero()) {
state_ = DONE;
break;
}
@@ -99,9 +117,16 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents(
// Fall through to forward the first event.
case MOVING:
{
- const float delta = floor(GetPositionDelta(interval));
- current_y_ += delta;
- ForwardMouseWheelEvent(target, delta);
+ // Even though WebMouseWheelEvents take floating point deltas,
+ // internally the scroll position is stored as an integer. We therefore
+ // keep track of the discrete delta which is consistent with the
+ // internal scrolling state. This ensures that when the gesture has
+ // finished we've scrolled exactly the specified distance.
+ total_delta_ += GetPositionDelta(interval);
+ gfx::Vector2d delta_discrete =
+ FloorTowardZero(total_delta_ - total_delta_discrete_);
+ ForwardMouseWheelEvent(target, delta_discrete);
+ total_delta_discrete_ += delta_discrete;
}
if (HasScrolledEntireDistance())
state_ = DONE;
@@ -125,9 +150,9 @@ void SyntheticSmoothScrollGesture::ForwardTouchEvent(
}
void SyntheticSmoothScrollGesture::ForwardMouseWheelEvent(
- SyntheticGestureTarget* target, float delta) const {
+ SyntheticGestureTarget* target, const gfx::Vector2dF& delta) const {
blink::WebMouseWheelEvent mouse_wheel_event =
- SyntheticWebMouseWheelEventBuilder::Build(0, delta, 0, false);
+ SyntheticWebMouseWheelEventBuilder::Build(delta.x(), delta.y(), 0, false);
mouse_wheel_event.x = params_.anchor.x();
mouse_wheel_event.y = params_.anchor.y();
@@ -136,30 +161,63 @@ void SyntheticSmoothScrollGesture::ForwardMouseWheelEvent(
InputEvent(mouse_wheel_event, ui::LatencyInfo(), false));
}
-float SyntheticSmoothScrollGesture::GetPositionDelta(
+void SyntheticSmoothScrollGesture::PressTouchPoint(
+ SyntheticGestureTarget* target) {
+ touch_event_.PressPoint(params_.anchor.x(), params_.anchor.y());
+ ForwardTouchEvent(target);
+}
+
+void SyntheticSmoothScrollGesture::MoveTouchPoint(
+ SyntheticGestureTarget* target) {
+ gfx::PointF touch_position = params_.anchor + total_delta_;
+ touch_event_.MovePoint(0, touch_position.x(), touch_position.y());
+ ForwardTouchEvent(target);
+}
+
+void SyntheticSmoothScrollGesture::ReleaseTouchPoint(
+ SyntheticGestureTarget* target) {
+ touch_event_.ReleasePoint(0);
+ ForwardTouchEvent(target);
+}
+
+void SyntheticSmoothScrollGesture::AddTouchSlopToDistance(
+ SyntheticGestureTarget* target) {
+ // Android uses euclidean distance to compute if a touch pointer has moved
+ // beyond the slop, while Aura uses Manhattan distance. We're using Euclidean
+ // distance and round up to the nearest integer.
+ // For vertical and horizontal scrolls (the common case), both methods produce
+ // the same result.
+ gfx::Vector2dF touch_slop_delta = ProjectLengthOntoScrollDirection(
+ target->GetTouchSlopInDips());
+ params_.distance += CeilFromZero(touch_slop_delta);
+}
+
+gfx::Vector2dF SyntheticSmoothScrollGesture::GetPositionDelta(
const base::TimeDelta& interval) const {
- float abs_delta = params_.speed_in_pixels_s * interval.InSecondsF();
+ float delta_length = params_.speed_in_pixels_s * interval.InSecondsF();
// Make sure we're not scrolling too far.
- abs_delta = std::min(abs_delta, ComputeAbsoluteRemainingDistance());
+ gfx::Vector2dF remaining_delta = ComputeRemainingDelta();
+ if (delta_length > remaining_delta.Length())
+ // In order to scroll in a certain direction we need to move the
+ // touch pointer/mouse wheel in the opposite direction.
+ return -remaining_delta;
+ else
+ return -ProjectLengthOntoScrollDirection(delta_length);
+}
- // A positive distance indicates scrolling down, which means the touch pointer
- // moves up or the scroll wheel moves down. In either case, the delta is
- // negative when scrolling down and positive when scrolling up.
- return params_.distance > 0 ? -abs_delta : abs_delta;
+gfx::Vector2dF SyntheticSmoothScrollGesture::ProjectLengthOntoScrollDirection(
+ float delta_length) const {
+ const float kTotalLength = params_.distance.Length();
+ return ScaleVector2d(params_.distance, delta_length / kTotalLength);
}
-float SyntheticSmoothScrollGesture::ComputeAbsoluteRemainingDistance() const {
- float remaining_distance =
- params_.distance - (params_.anchor.y() - current_y_);
- float abs_remaining_distance =
- params_.distance > 0 ? remaining_distance : -remaining_distance;
- DCHECK_GE(abs_remaining_distance, 0);
- return abs_remaining_distance;
+gfx::Vector2dF SyntheticSmoothScrollGesture::ComputeRemainingDelta() const {
+ return params_.distance + total_delta_;
}
bool SyntheticSmoothScrollGesture::HasScrolledEntireDistance() const {
- return ComputeAbsoluteRemainingDistance() == 0;
+ return ComputeRemainingDelta().IsZero();
}
} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
index 10428b16e1..53b4da5468 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
@@ -8,10 +8,12 @@
#include "base/time/time.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
#include "content/common/content_export.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/vector2d.h"
+#include "ui/gfx/vector2d_f.h"
namespace content {
@@ -32,12 +34,6 @@ class CONTENT_EXPORT SyntheticSmoothScrollGesture : public SyntheticGesture {
STOPPING,
DONE
};
- SyntheticSmoothScrollGestureParams params_;
- float current_y_;
- SyntheticWebTouchEvent touch_event_;
- SyntheticGestureParams::GestureSourceType gesture_source_type_;
- GestureState state_;
- base::TimeDelta total_stopping_wait_time_;
void ForwardTouchInputEvents(
const base::TimeDelta& interval, SyntheticGestureTarget* target);
@@ -46,12 +42,26 @@ class CONTENT_EXPORT SyntheticSmoothScrollGesture : public SyntheticGesture {
void ForwardTouchEvent(SyntheticGestureTarget* target) const;
void ForwardMouseWheelEvent(SyntheticGestureTarget* target,
- float delta) const;
+ const gfx::Vector2dF& delta) const;
+
+ void PressTouchPoint(SyntheticGestureTarget* target);
+ void MoveTouchPoint(SyntheticGestureTarget* target);
+ void ReleaseTouchPoint(SyntheticGestureTarget* target);
- float GetPositionDelta(const base::TimeDelta& interval) const;
- float ComputeAbsoluteRemainingDistance() const;
+ void AddTouchSlopToDistance(SyntheticGestureTarget* target);
+ gfx::Vector2dF GetPositionDelta(const base::TimeDelta& interval) const;
+ gfx::Vector2dF ProjectLengthOntoScrollDirection(float delta_length) const;
+ gfx::Vector2dF ComputeRemainingDelta() const;
bool HasScrolledEntireDistance() const;
+ SyntheticSmoothScrollGestureParams params_;
+ gfx::Vector2dF total_delta_;
+ gfx::Vector2d total_delta_discrete_;
+ SyntheticWebTouchEvent touch_event_;
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ GestureState state_;
+ base::TimeDelta total_stopping_wait_time_;
+
DISALLOW_COPY_AND_ASSIGN(SyntheticSmoothScrollGesture);
};
diff --git a/content/browser/renderer_host/input/synthetic_tap_gesture.cc b/content/browser/renderer_host/input/synthetic_tap_gesture.cc
new file mode 100644
index 0000000000..1f15d82f01
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_tap_gesture.cc
@@ -0,0 +1,119 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
+
+#include "base/logging.h"
+#include "content/common/input/input_event.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/events/latency_info.h"
+
+namespace content {
+namespace {
+
+void DispatchEventToPlatform(SyntheticGestureTarget* target,
+ const blink::WebInputEvent& event) {
+ target->DispatchInputEventToPlatform(
+ InputEvent(event, ui::LatencyInfo(), false));
+}
+
+} // namespace
+
+SyntheticTapGesture::SyntheticTapGesture(
+ const SyntheticTapGestureParams& params)
+ : params_(params),
+ gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
+ state_(SETUP) {
+ DCHECK_GE(params_.duration_ms, 0);
+}
+
+SyntheticTapGesture::~SyntheticTapGesture() {}
+
+SyntheticGesture::Result SyntheticTapGesture::ForwardInputEvents(
+ const base::TimeDelta& interval, SyntheticGestureTarget* target) {
+ if (state_ == SETUP) {
+ gesture_source_type_ = params_.gesture_source_type;
+ if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
+ gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
+
+ if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_))
+ return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM;
+
+ state_ = PRESS;
+ }
+
+ DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
+ if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT ||
+ gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT)
+ ForwardTouchOrMouseInputEvents(interval, target);
+ else
+ return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
+
+ return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED
+ : SyntheticGesture::GESTURE_RUNNING;
+}
+
+void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
+ const base::TimeDelta& interval, SyntheticGestureTarget* target) {
+ switch (state_) {
+ case PRESS:
+ Press(target);
+ // Release immediately if duration is 0.
+ if (params_.duration_ms == 0) {
+ Release(target);
+ state_ = DONE;
+ } else {
+ state_ = WAITING_TO_RELEASE;
+ }
+ break;
+ case WAITING_TO_RELEASE:
+ total_waiting_time_ += interval;
+ if (total_waiting_time_ >=
+ base::TimeDelta::FromMilliseconds(params_.duration_ms)) {
+ Release(target);
+ state_ = DONE;
+ }
+ break;
+ case SETUP:
+ NOTREACHED() << "State SETUP invalid for synthetic tap gesture.";
+ case DONE:
+ NOTREACHED() << "State DONE invalid for synthetic tap gesture.";
+ }
+}
+
+void SyntheticTapGesture::Press(SyntheticGestureTarget* target) {
+ if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
+ touch_event_.PressPoint(params_.position.x(), params_.position.y());
+ DispatchEventToPlatform(target, touch_event_);
+ } else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) {
+ blink::WebMouseEvent mouse_event =
+ SyntheticWebMouseEventBuilder::Build(blink::WebInputEvent::MouseDown,
+ params_.position.x(),
+ params_.position.y(),
+ 0);
+ mouse_event.clickCount = 1;
+ DispatchEventToPlatform(target, mouse_event);
+ } else {
+ NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
+ }
+}
+
+void SyntheticTapGesture::Release(SyntheticGestureTarget* target) {
+ if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
+ touch_event_.ReleasePoint(0);
+ DispatchEventToPlatform(target, touch_event_);
+ } else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) {
+ blink::WebMouseEvent mouse_event =
+ SyntheticWebMouseEventBuilder::Build(blink::WebInputEvent::MouseUp,
+ params_.position.x(),
+ params_.position.y(),
+ 0);
+ mouse_event.clickCount = 1;
+ DispatchEventToPlatform(target, mouse_event);
+ } else {
+ NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
+ }
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_tap_gesture.h b/content/browser/renderer_host/input/synthetic_tap_gesture.h
new file mode 100644
index 0000000000..22217f9909
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_tap_gesture.h
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TAP_GESTURE_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TAP_GESTURE_H_
+
+#include "content/browser/renderer_host/input/synthetic_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "content/common/content_export.h"
+#include "content/common/input/synthetic_tap_gesture_params.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+
+namespace content {
+
+class CONTENT_EXPORT SyntheticTapGesture : public SyntheticGesture {
+ public:
+ explicit SyntheticTapGesture(const SyntheticTapGestureParams& params);
+ virtual ~SyntheticTapGesture();
+
+ virtual SyntheticGesture::Result ForwardInputEvents(
+ const base::TimeDelta& interval, SyntheticGestureTarget* target) OVERRIDE;
+
+ private:
+ enum GestureState {
+ SETUP,
+ PRESS,
+ WAITING_TO_RELEASE,
+ DONE
+ };
+
+ void ForwardTouchOrMouseInputEvents(const base::TimeDelta& interval,
+ SyntheticGestureTarget* target);
+
+ void Press(SyntheticGestureTarget* target);
+ void Release(SyntheticGestureTarget* target);
+
+ SyntheticTapGestureParams params_;
+ base::TimeDelta total_waiting_time_;
+ SyntheticWebTouchEvent touch_event_;
+ SyntheticGestureParams::GestureSourceType gesture_source_type_;
+ GestureState state_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticTapGesture);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_TAP_GESTURE_H_
diff --git a/content/browser/renderer_host/input/synthetic_web_input_event_builders.cc b/content/browser/renderer_host/input/synthetic_web_input_event_builders.cc
deleted file mode 100644
index 09f38dc569..0000000000
--- a/content/browser/renderer_host/input/synthetic_web_input_event_builders.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
-
-#include "base/logging.h"
-#include "content/browser/renderer_host/input/web_input_event_util.h"
-#include "ui/events/keycodes/keyboard_codes.h"
-
-namespace content {
-
-using blink::WebInputEvent;
-using blink::WebKeyboardEvent;
-using blink::WebGestureEvent;
-using blink::WebMouseEvent;
-using blink::WebMouseWheelEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-WebMouseEvent SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::Type type) {
- WebMouseEvent result;
- result.type = type;
- return result;
-}
-
-WebMouseEvent SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::Type type,
- int window_x,
- int window_y,
- int modifiers) {
- DCHECK(WebInputEvent::isMouseEventType(type));
- WebMouseEvent result = Build(type);
- result.x = window_x;
- result.y = window_y;
- result.windowX = window_x;
- result.windowY = window_y;
- result.modifiers = modifiers;
-
- if (type == WebInputEvent::MouseDown || type == WebInputEvent::MouseUp)
- result.button = WebMouseEvent::ButtonLeft;
- else
- result.button = WebMouseEvent::ButtonNone;
-
- return result;
-}
-
-WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
- WebMouseWheelEvent::Phase phase) {
- WebMouseWheelEvent result;
- result.type = WebInputEvent::MouseWheel;
- result.phase = phase;
- return result;
-}
-
-WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(float dx,
- float dy,
- int modifiers,
- bool precise) {
- WebMouseWheelEvent result;
- result.type = WebInputEvent::MouseWheel;
- result.deltaX = dx;
- result.deltaY = dy;
- result.modifiers = modifiers;
- result.hasPreciseScrollingDeltas = precise;
- return result;
-}
-
-NativeWebKeyboardEvent SyntheticWebKeyboardEventBuilder::Build(
- WebInputEvent::Type type) {
- DCHECK(WebInputEvent::isKeyboardEventType(type));
- NativeWebKeyboardEvent result;
- result.type = type;
- result.windowsKeyCode = ui::VKEY_L; // non-null made up value.
- return result;
-}
-
-WebGestureEvent SyntheticWebGestureEventBuilder::Build(
- WebInputEvent::Type type,
- WebGestureEvent::SourceDevice source_device) {
- DCHECK(WebInputEvent::isGestureEventType(type));
- WebGestureEvent result;
- result.type = type;
- result.sourceDevice = source_device;
- return result;
-}
-
-WebGestureEvent SyntheticWebGestureEventBuilder::BuildScrollUpdate(
- float dx,
- float dy,
- int modifiers) {
- WebGestureEvent result = Build(WebInputEvent::GestureScrollUpdate,
- WebGestureEvent::Touchscreen);
- result.data.scrollUpdate.deltaX = dx;
- result.data.scrollUpdate.deltaY = dy;
- result.modifiers = modifiers;
- return result;
-}
-
-WebGestureEvent SyntheticWebGestureEventBuilder::BuildPinchUpdate(
- float scale,
- float anchor_x,
- float anchor_y,
- int modifiers) {
- WebGestureEvent result = Build(WebInputEvent::GesturePinchUpdate,
- WebGestureEvent::Touchscreen);
- result.data.pinchUpdate.scale = scale;
- result.x = anchor_x;
- result.y = anchor_y;
- result.modifiers = modifiers;
- return result;
-}
-
-WebGestureEvent SyntheticWebGestureEventBuilder::BuildFling(
- float velocity_x,
- float velocity_y,
- WebGestureEvent::SourceDevice source_device) {
- WebGestureEvent result = Build(WebInputEvent::GestureFlingStart,
- source_device);
- result.data.flingStart.velocityX = velocity_x;
- result.data.flingStart.velocityY = velocity_y;
- return result;
-}
-
-SyntheticWebTouchEvent::SyntheticWebTouchEvent() : WebTouchEvent() {}
-
-void SyntheticWebTouchEvent::ResetPoints() {
- int point = 0;
- for (unsigned int i = 0; i < touchesLength; ++i) {
- if (touches[i].state == WebTouchPoint::StateReleased)
- continue;
-
- touches[point] = touches[i];
- touches[point].state = WebTouchPoint::StateStationary;
- ++point;
- }
- touchesLength = point;
- type = WebInputEvent::Undefined;
-}
-
-int SyntheticWebTouchEvent::PressPoint(int x, int y) {
- if (touchesLength == touchesLengthCap)
- return -1;
- WebTouchPoint& point = touches[touchesLength];
- point.id = touchesLength;
- point.position.x = point.screenPosition.x = x;
- point.position.y = point.screenPosition.y = y;
- point.state = WebTouchPoint::StatePressed;
- point.radiusX = point.radiusY = 1.f;
- ++touchesLength;
- type = WebInputEvent::TouchStart;
- return point.id;
-}
-
-void SyntheticWebTouchEvent::MovePoint(int index, int x, int y) {
- CHECK(index >= 0 && index < touchesLengthCap);
- WebTouchPoint& point = touches[index];
- point.position.x = point.screenPosition.x = x;
- point.position.y = point.screenPosition.y = y;
- touches[index].state = WebTouchPoint::StateMoved;
- type = WebInputEvent::TouchMove;
-}
-
-void SyntheticWebTouchEvent::ReleasePoint(int index) {
- CHECK(index >= 0 && index < touchesLengthCap);
- touches[index].state = WebTouchPoint::StateReleased;
- type = WebInputEvent::TouchEnd;
-}
-
-void SyntheticWebTouchEvent::CancelPoint(int index) {
- CHECK(index >= 0 && index < touchesLengthCap);
- touches[index].state = WebTouchPoint::StateCancelled;
- type = WebInputEvent::TouchCancel;
-}
-
-void SyntheticWebTouchEvent::SetTimestamp(base::TimeDelta timestamp) {
- timeStampSeconds = timestamp.InSecondsF();
-}
-
-SyntheticWebTouchEvent SyntheticWebTouchEventBuilder::Build(
- WebInputEvent::Type type) {
- DCHECK(WebInputEvent::isTouchEventType(type));
- SyntheticWebTouchEvent result;
- result.type = type;
- return result;
-};
-
-} // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_web_input_event_builders.h b/content/browser/renderer_host/input/synthetic_web_input_event_builders.h
deleted file mode 100644
index 754f42df5f..0000000000
--- a/content/browser/renderer_host/input/synthetic_web_input_event_builders.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_WEB_INPUT_EVENT_BUILDERS_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_WEB_INPUT_EVENT_BUILDERS_H_
-
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-// Provides sensible creation of default WebInputEvents for testing purposes.
-
-namespace content {
-
-class CONTENT_EXPORT SyntheticWebMouseEventBuilder {
- public:
- static blink::WebMouseEvent Build(blink::WebInputEvent::Type type);
- static blink::WebMouseEvent Build(blink::WebInputEvent::Type type,
- int window_x,
- int window_y,
- int modifiers);
-};
-
-class CONTENT_EXPORT SyntheticWebMouseWheelEventBuilder {
- public:
- static blink::WebMouseWheelEvent Build(
- blink::WebMouseWheelEvent::Phase phase);
- static blink::WebMouseWheelEvent Build(float dx,
- float dy,
- int modifiers,
- bool precise);
-};
-
-class CONTENT_EXPORT SyntheticWebKeyboardEventBuilder {
- public:
- static NativeWebKeyboardEvent Build(blink::WebInputEvent::Type type);
-};
-
-class CONTENT_EXPORT SyntheticWebGestureEventBuilder {
- public:
- static blink::WebGestureEvent Build(
- blink::WebInputEvent::Type type,
- blink::WebGestureEvent::SourceDevice sourceDevice);
- static blink::WebGestureEvent BuildScrollUpdate(float dx,
- float dY,
- int modifiers);
- static blink::WebGestureEvent BuildPinchUpdate(float scale,
- float anchor_x,
- float anchor_y,
- int modifiers);
- static blink::WebGestureEvent BuildFling(
- float velocity_x,
- float velocity_y,
- blink::WebGestureEvent::SourceDevice source_device);
-};
-
-class CONTENT_EXPORT SyntheticWebTouchEvent
- : public NON_EXPORTED_BASE(blink::WebTouchEvent) {
- public:
- SyntheticWebTouchEvent();
-
- // Mark all the points as stationary, and remove any released points.
- void ResetPoints();
-
- // Adds an additional point to the touch list, returning the point's index.
- int PressPoint(int x, int y);
- void MovePoint(int index, int x, int y);
- void ReleasePoint(int index);
- void CancelPoint(int index);
-
- void SetTimestamp(base::TimeDelta timestamp);
-};
-
-class CONTENT_EXPORT SyntheticWebTouchEventBuilder {
- public:
- static SyntheticWebTouchEvent Build(blink::WebInputEvent::Type type);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_WEB_INPUT_EVENT_BUILDERS_H_
diff --git a/content/browser/renderer_host/input/timeout_monitor.cc b/content/browser/renderer_host/input/timeout_monitor.cc
new file mode 100644
index 0000000000..93b310286b
--- /dev/null
+++ b/content/browser/renderer_host/input/timeout_monitor.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/timeout_monitor.h"
+
+using base::Time;
+using base::TimeDelta;
+
+namespace content {
+
+TimeoutMonitor::TimeoutMonitor(const TimeoutHandler& timeout_handler)
+ : timeout_handler_(timeout_handler) {
+ DCHECK(!timeout_handler_.is_null());
+}
+
+TimeoutMonitor::~TimeoutMonitor() {}
+
+void TimeoutMonitor::Start(TimeDelta delay) {
+ // Set time_when_considered_timed_out_ if it's null. Also, update
+ // time_when_considered_timed_out_ if the caller's request is sooner than the
+ // existing one. This will have the side effect that the existing timeout will
+ // be forgotten.
+ Time requested_end_time = Time::Now() + delay;
+ if (time_when_considered_timed_out_.is_null() ||
+ time_when_considered_timed_out_ > requested_end_time)
+ time_when_considered_timed_out_ = requested_end_time;
+
+ // If we already have a timer with the same or shorter duration, then we can
+ // wait for it to finish.
+ if (timeout_timer_.IsRunning() && timeout_timer_.GetCurrentDelay() <= delay) {
+ // If time_when_considered_timed_out_ was null, this timer may fire early.
+ // CheckTimedOut handles that that by calling Start with the remaining time.
+ // If time_when_considered_timed_out_ was non-null, it means we still
+ // haven't been stopped, so we leave time_when_considered_timed_out_ as is.
+ return;
+ }
+
+ // Either the timer is not yet running, or we need to adjust the timer to
+ // fire sooner.
+ time_when_considered_timed_out_ = requested_end_time;
+ timeout_timer_.Stop();
+ timeout_timer_.Start(FROM_HERE, delay, this, &TimeoutMonitor::CheckTimedOut);
+}
+
+void TimeoutMonitor::Restart(TimeDelta delay) {
+ // Setting to null will cause StartTimeoutMonitor to restart the timer.
+ time_when_considered_timed_out_ = Time();
+ Start(delay);
+}
+
+void TimeoutMonitor::Stop() {
+ // We do not bother to stop the timeout_timer_ here in case it will be
+ // started again shortly, which happens to be the common use case.
+ time_when_considered_timed_out_ = Time();
+}
+
+void TimeoutMonitor::CheckTimedOut() {
+ // If we received a call to |Stop()|.
+ if (time_when_considered_timed_out_.is_null())
+ return;
+
+ // If we have not waited long enough, then wait some more.
+ Time now = Time::Now();
+ if (now < time_when_considered_timed_out_) {
+ Start(time_when_considered_timed_out_ - now);
+ return;
+ }
+
+ timeout_handler_.Run();
+}
+
+bool TimeoutMonitor::IsRunning() const {
+ return timeout_timer_.IsRunning() &&
+ !time_when_considered_timed_out_.is_null();
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/timeout_monitor.h b/content/browser/renderer_host/input/timeout_monitor.h
new file mode 100644
index 0000000000..88154e86e7
--- /dev/null
+++ b/content/browser/renderer_host/input/timeout_monitor.h
@@ -0,0 +1,50 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TIMEOUT_MONITOR_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TIMEOUT_MONITOR_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Utility class for handling a timeout callback with periodic starts and stops.
+class CONTENT_EXPORT TimeoutMonitor {
+ public:
+ typedef base::Closure TimeoutHandler;
+
+ explicit TimeoutMonitor(const TimeoutHandler& timeout_handler);
+ ~TimeoutMonitor();
+
+ // Schedule the timeout timer to fire at |delay| into the future. If a timeout
+ // has already been scheduled, reschedule only if |delay| is sooner than the
+ // currently scheduled timeout time.
+ void Start(base::TimeDelta delay);
+
+ void Restart(base::TimeDelta delay);
+ void Stop();
+ bool IsRunning() const;
+
+ private:
+ void CheckTimedOut();
+
+ TimeoutHandler timeout_handler_;
+
+ // Indicates a time in the future when we would consider the input as
+ // having timed out, if it does not receive an appropriate stop request.
+ base::Time time_when_considered_timed_out_;
+
+ // This timer runs to check if |time_when_considered_timed_out_| has past.
+ base::OneShotTimer<TimeoutMonitor> timeout_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(TimeoutMonitor);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TIMEOUT_MONITOR_H_
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc
new file mode 100644
index 0000000000..665ff15bd3
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -0,0 +1,63 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touch_action_filter.h"
+
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+using blink::WebInputEvent;
+using blink::WebGestureEvent;
+
+namespace content {
+
+TouchActionFilter::TouchActionFilter() :
+ drop_scroll_gesture_events_(false),
+ allowed_touch_action_(TOUCH_ACTION_AUTO) {
+}
+
+bool TouchActionFilter::FilterGestureEvent(
+ const WebGestureEvent& gesture_event) {
+ // Filter for allowable touch actions first (eg. before the TouchEventQueue
+ // can decide to send a touch cancel event).
+ // TODO(rbyers): Add touch-action control over for pinch. crbug.com/247566.
+ switch(gesture_event.type) {
+ case WebInputEvent::GestureScrollBegin:
+ if (allowed_touch_action_ == TOUCH_ACTION_NONE)
+ drop_scroll_gesture_events_ = true;
+ // FALL THROUGH
+ case WebInputEvent::GestureScrollUpdate:
+ if (drop_scroll_gesture_events_)
+ return true;
+ break;
+
+ case WebInputEvent::GestureScrollEnd:
+ case WebInputEvent::GestureFlingStart:
+ allowed_touch_action_ = content::TOUCH_ACTION_AUTO;
+ if (drop_scroll_gesture_events_) {
+ drop_scroll_gesture_events_ = false;
+ return true;
+ }
+ break;
+
+ default:
+ // Gesture events unrelated to touch actions (panning/zooming) are left
+ // alone.
+ break;
+ }
+
+ return false;
+}
+
+void TouchActionFilter::OnSetTouchAction(
+ content::TouchAction touch_action) {
+ // For multiple fingers, we take the intersection of the touch actions for
+ // all fingers that have gone down during this action.
+ // TODO(rbyers): What exact multi-finger semantic do we want? This is left
+ // as implementation-defined in the pointer events specification.
+ // crbug.com/247566.
+ if (touch_action == content::TOUCH_ACTION_NONE)
+ allowed_touch_action_ = content::TOUCH_ACTION_NONE;
+}
+
+}
diff --git a/content/browser/renderer_host/input/touch_action_filter.h b/content/browser/renderer_host/input/touch_action_filter.h
new file mode 100644
index 0000000000..6485c45a93
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_action_filter.h
@@ -0,0 +1,45 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "content/common/input/touch_action.h"
+
+namespace blink {
+class WebGestureEvent;
+}
+
+namespace content {
+
+// The TouchActionFilter is responsible for filtering scroll and pinch gesture
+// events according to the CSS touch-action values the renderer has sent for
+// each touch point.
+// For details see the touch-action design doc at http://goo.gl/KcKbxQ.
+class CONTENT_EXPORT TouchActionFilter {
+public:
+ TouchActionFilter();
+
+ // Returns true if the supplied gesture event should be dropped based on
+ // the current touch-action state.
+ bool FilterGestureEvent(const blink::WebGestureEvent& gesture_event);
+
+ // Called when a set-touch-action message is received from the renderer
+ // for a touch start event that is currently in flight.
+ void OnSetTouchAction(content::TouchAction touch_action);
+
+private:
+ // Whether GestureScroll events should be discarded due to touch-action.
+ bool drop_scroll_gesture_events_;
+
+ // What touch actions are currently permitted.
+ content::TouchAction allowed_touch_action_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchActionFilter);
+};
+
+}
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
new file mode 100644
index 0000000000..a07ef09dfb
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -0,0 +1,100 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touch_action_filter.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+#include "content/port/browser/event_with_latency_info.h"
+#include "content/port/common/input_event_ack_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+using blink::WebGestureEvent;
+using blink::WebInputEvent;
+
+namespace content {
+
+TEST(TouchActionFilterTest, SimpleFilter) {
+ TouchActionFilter filter;
+
+ const WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::GestureScrollBegin, WebGestureEvent::Touchscreen);
+ const WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(0, 10, 0);
+ const WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
+ const WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
+
+ // No events filtered by default.
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_end));
+ EXPECT_FALSE(filter.FilterGestureEvent(tap));
+
+ // TOUCH_ACTION_AUTO doesn't cause any filtering.
+ filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_end));
+
+ // TOUCH_ACTION_NONE filters out all scroll events, but no other events.
+ filter.OnSetTouchAction(TOUCH_ACTION_NONE);
+ EXPECT_FALSE(filter.FilterGestureEvent(tap));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_end));
+
+ // After the end of a gesture the state is reset.
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_end));
+
+ // Setting touch action doesn't impact any in-progress gestures.
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_begin));
+ filter.OnSetTouchAction(TOUCH_ACTION_NONE);
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_end));
+
+ // And the state is still cleared for the next gesture.
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_FALSE(filter.FilterGestureEvent(scroll_end));
+
+ // Changing the touch action during a gesture has no effect.
+ filter.OnSetTouchAction(TOUCH_ACTION_NONE);
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_begin));
+ filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_end));
+}
+
+TEST(TouchActionFilterTest, MultiTouch) {
+ TouchActionFilter filter;
+
+ const WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::GestureScrollBegin, WebGestureEvent::Touchscreen);
+ const WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(0, 10, 0);
+ const WebGestureEvent scrollEnd = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::GestureScrollEnd, WebGestureEvent::Touchscreen);
+
+ // For multiple points, the intersection is what matters.
+ filter.OnSetTouchAction(TOUCH_ACTION_NONE);
+ filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scrollEnd));
+
+ filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
+ filter.OnSetTouchAction(TOUCH_ACTION_NONE);
+ filter.OnSetTouchAction(TOUCH_ACTION_AUTO);
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_begin));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scroll_update));
+ EXPECT_TRUE(filter.FilterGestureEvent(scrollEnd));
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
index ecc1205672..3524b18250 100644
--- a/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -5,13 +5,165 @@
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "base/auto_reset.h"
+#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/stl_util.h"
+#include "content/browser/renderer_host/input/timeout_monitor.h"
+#include "content/common/input/web_input_event_traits.h"
+#include "content/public/common/content_switches.h"
+
+using blink::WebInputEvent;
+using blink::WebTouchEvent;
+using blink::WebTouchPoint;
namespace content {
+namespace {
+
+const InputEventAckState kDefaultNotForwardedAck =
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
+TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
+ const TouchEventWithLatencyInfo& event_to_cancel) {
+ TouchEventWithLatencyInfo event = event_to_cancel;
+ event.event.type = WebInputEvent::TouchCancel;
+ for (size_t i = 0; i < event.event.touchesLength; i++)
+ event.event.touches[i].state = WebTouchPoint::StateCancelled;
+ return event;
+}
+
+bool IsNewTouchGesture(const WebTouchEvent& event) {
+ if (event.type != WebInputEvent::TouchStart)
+ return false;
+ if (!event.touchesLength)
+ return false;
+ for (size_t i = 0; i < event.touchesLength; i++) {
+ if (event.touches[i].state != WebTouchPoint::StatePressed)
+ return false;
+ }
+ return true;
+}
+
+bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) {
+ return type == WebInputEvent::TouchStart ||
+ type == WebInputEvent::TouchMove;
+}
+
+} // namespace
+
+class TouchEventQueue::TouchTimeoutHandler {
+ public:
+ TouchTimeoutHandler(TouchEventQueue* touch_queue, size_t timeout_delay_ms)
+ : touch_queue_(touch_queue),
+ timeout_delay_(base::TimeDelta::FromMilliseconds(timeout_delay_ms)),
+ pending_ack_state_(PENDING_ACK_NONE),
+ timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut,
+ base::Unretained(this))) {}
+
+ ~TouchTimeoutHandler() {}
+
+ void Start(const TouchEventWithLatencyInfo& event) {
+ DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
+ DCHECK(ShouldTouchTypeTriggerTimeout(event.event.type));
+ timeout_event_ = event;
+ timeout_monitor_.Restart(timeout_delay_);
+ }
+
+ bool ConfirmTouchEvent(InputEventAckState ack_result) {
+ switch (pending_ack_state_) {
+ case PENDING_ACK_NONE:
+ timeout_monitor_.Stop();
+ return false;
+ case PENDING_ACK_ORIGINAL_EVENT:
+ if (AckedTimeoutEventRequiresCancel(ack_result)) {
+ SetPendingAckState(PENDING_ACK_CANCEL_EVENT);
+ TouchEventWithLatencyInfo cancel_event =
+ ObtainCancelEventForTouchEvent(timeout_event_);
+ touch_queue_->UpdateTouchAckStates(
+ cancel_event.event, kDefaultNotForwardedAck);
+ touch_queue_->client_->SendTouchEventImmediately(cancel_event);
+ } else {
+ SetPendingAckState(PENDING_ACK_NONE);
+ touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result);
+ }
+ return true;
+ case PENDING_ACK_CANCEL_EVENT:
+ SetPendingAckState(PENDING_ACK_NONE);
+ return true;
+ }
+ return false;
+ }
+
+ bool HasTimeoutEvent() const {
+ return pending_ack_state_ != PENDING_ACK_NONE;
+ }
+
+ bool IsTimeoutTimerRunning() const {
+ return timeout_monitor_.IsRunning();
+ }
+
+ private:
+ enum PendingAckState {
+ PENDING_ACK_NONE,
+ PENDING_ACK_ORIGINAL_EVENT,
+ PENDING_ACK_CANCEL_EVENT,
+ };
+
+ void OnTimeOut() {
+ SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT);
+ touch_queue_->FlushQueue();
+ }
+
+ // Skip a cancel event if the timed-out event had no consumer and was the
+ // initial event in the gesture.
+ bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const {
+ DCHECK(HasTimeoutEvent());
+ if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)
+ return true;
+ return !IsNewTouchGesture(timeout_event_.event);
+ }
+
+ void SetPendingAckState(PendingAckState new_pending_ack_state) {
+ DCHECK_NE(pending_ack_state_, new_pending_ack_state);
+ switch (new_pending_ack_state) {
+ case PENDING_ACK_ORIGINAL_EVENT:
+ DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
+ TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this);
+ break;
+ case PENDING_ACK_CANCEL_EVENT:
+ DCHECK_EQ(pending_ack_state_, PENDING_ACK_ORIGINAL_EVENT);
+ DCHECK(!timeout_monitor_.IsRunning());
+ DCHECK(touch_queue_->empty());
+ TRACE_EVENT_ASYNC_STEP_INTO0(
+ "input", "TouchEventTimeout", this, "CancelEvent");
+ break;
+ case PENDING_ACK_NONE:
+ DCHECK(!timeout_monitor_.IsRunning());
+ DCHECK(touch_queue_->empty());
+ TRACE_EVENT_ASYNC_END0("input", "TouchEventTimeout", this);
+ break;
+ }
+ pending_ack_state_ = new_pending_ack_state;
+ }
+
+
+ TouchEventQueue* touch_queue_;
+
+ // How long to wait on a touch ack before cancelling the touch sequence.
+ base::TimeDelta timeout_delay_;
+
+ // The touch event source for which we expect the next ack.
+ PendingAckState pending_ack_state_;
+
+ // The event for which the ack timeout is triggered.
+ TouchEventWithLatencyInfo timeout_event_;
+
+ // Provides timeout-based callback behavior.
+ TimeoutMonitor timeout_monitor_;
+};
+
+
// This class represents a single coalesced touch event. However, it also keeps
// track of all the original touch-events that were coalesced into a single
// event. The coalesced event is forwarded to the renderer, while the original
@@ -19,9 +171,10 @@ typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
// the Client receives the event with their original timestamp.
class CoalescedWebTouchEvent {
public:
- explicit CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event)
+ CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event,
+ bool ignore_ack)
: coalesced_event_(event),
- ignore_ack_(false) {
+ ignore_ack_(ignore_ack) {
events_.push_back(event);
TRACE_EVENT_ASYNC_BEGIN0(
"input", "TouchEventQueue::QueueEvent", this);
@@ -64,7 +217,6 @@ class CoalescedWebTouchEvent {
size_t size() const { return events_.size(); }
bool ignore_ack() const { return ignore_ack_; }
- void set_ignore_ack(bool value) { ignore_ack_ = value; }
private:
// This is the event that is forwarded to the renderer.
@@ -83,7 +235,10 @@ class CoalescedWebTouchEvent {
TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client)
: client_(client),
dispatching_touch_ack_(NULL),
- no_touch_to_renderer_(false) {
+ dispatching_touch_(false),
+ no_touch_to_renderer_(false),
+ renderer_is_consuming_touch_gesture_(false),
+ ack_timeout_enabled_(false) {
DCHECK(client);
}
@@ -98,7 +253,7 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
if (touch_queue_.empty() && !dispatching_touch_ack_) {
// There is no touch event in the queue. Forward it to the renderer
// immediately.
- touch_queue_.push_back(new CoalescedWebTouchEvent(event));
+ touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
TryForwardNextEventToRenderer();
return;
}
@@ -110,35 +265,26 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
if (last_event->CoalesceEventIfPossible(event))
return;
}
- touch_queue_.push_back(new CoalescedWebTouchEvent(event));
+ touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
}
void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result,
const ui::LatencyInfo& latency_info) {
DCHECK(!dispatching_touch_ack_);
+ dispatching_touch_ = false;
+
+ if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result))
+ return;
+
if (touch_queue_.empty())
return;
- // Update the ACK status for each touch point in the ACKed event.
- const blink::WebTouchEvent& event =
- touch_queue_.front()->coalesced_event().event;
- if (event.type == blink::WebInputEvent::TouchEnd ||
- event.type == blink::WebInputEvent::TouchCancel) {
- // The points have been released. Erase the ACK states.
- for (unsigned i = 0; i < event.touchesLength; ++i) {
- const blink::WebTouchPoint& point = event.touches[i];
- if (point.state == blink::WebTouchPoint::StateReleased ||
- point.state == blink::WebTouchPoint::StateCancelled)
- touch_ack_states_.erase(point.id);
- }
- } else if (event.type == blink::WebInputEvent::TouchStart) {
- for (unsigned i = 0; i < event.touchesLength; ++i) {
- const blink::WebTouchPoint& point = event.touches[i];
- if (point.state == blink::WebTouchPoint::StatePressed)
- touch_ack_states_[point.id] = ack_result;
- }
- }
+ if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
+ renderer_is_consuming_touch_gesture_ = true;
+ const WebTouchEvent& acked_event =
+ touch_queue_.front()->coalesced_event().event;
+ UpdateTouchAckStates(acked_event, ack_result);
PopTouchEventToClient(ack_result, latency_info);
TryForwardNextEventToRenderer();
}
@@ -150,12 +296,29 @@ void TouchEventQueue::TryForwardNextEventToRenderer() {
while (!touch_queue_.empty()) {
const TouchEventWithLatencyInfo& touch =
touch_queue_.front()->coalesced_event();
+ if (IsNewTouchGesture(touch.event))
+ renderer_is_consuming_touch_gesture_ = false;
if (ShouldForwardToRenderer(touch.event)) {
- client_->SendTouchEventImmediately(touch);
+ ForwardToRenderer(touch);
break;
}
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
- ui::LatencyInfo());
+ PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo());
+ }
+}
+
+void TouchEventQueue::ForwardToRenderer(
+ const TouchEventWithLatencyInfo& touch) {
+ DCHECK(!dispatching_touch_);
+ // A synchronous ack will reset |dispatching_touch_|, in which case
+ // the touch timeout should not be started.
+ base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
+ client_->SendTouchEventImmediately(touch);
+ if (ack_timeout_enabled_ &&
+ dispatching_touch_ &&
+ !renderer_is_consuming_touch_gesture_ &&
+ ShouldTouchTypeTriggerTimeout(touch.event.type)) {
+ DCHECK(timeout_handler_);
+ timeout_handler_->Start(touch);
}
}
@@ -170,24 +333,21 @@ void TouchEventQueue::OnGestureScrollEvent(
if (no_touch_to_renderer_ || !dispatching_touch_ack_)
return;
no_touch_to_renderer_ = true;
+
+ // If we have a timeout event, a cancel has already been dispatched
+ // for the current touch stream.
+ if (HasTimeoutEvent())
+ return;
+
// Fake a TouchCancel to cancel the touch points of the touch event
// that is currently being acked.
- TouchEventWithLatencyInfo cancel_event =
- dispatching_touch_ack_->coalesced_event();
- cancel_event.event.type = blink::WebInputEvent::TouchCancel;
- for (size_t i = 0; i < cancel_event.event.touchesLength; i++)
- cancel_event.event.touches[i].state =
- blink::WebTouchPoint::StateCancelled;
- CoalescedWebTouchEvent* coalesced_cancel_event =
- new CoalescedWebTouchEvent(cancel_event);
- // Ignore the ack of the touch cancel so when it is acked, it won't get
- // sent to gesture recognizer.
- coalesced_cancel_event->set_ignore_ack(true);
- // |dispatching_touch_ack_| is non-null when we reach here, meaning we
+ // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we
// are in the scope of PopTouchEventToClient() and that no touch event
// in the queue is waiting for ack from renderer. So we can just insert
// the touch cancel at the beginning of the queue.
- touch_queue_.push_front(coalesced_cancel_event);
+ touch_queue_.push_front(new CoalescedWebTouchEvent(
+ ObtainCancelEventForTouchEvent(
+ dispatching_touch_ack_->coalesced_event()), true));
} else if (type == blink::WebInputEvent::GestureScrollEnd ||
type == blink::WebInputEvent::GestureFlingStart) {
no_touch_to_renderer_ = false;
@@ -196,22 +356,52 @@ void TouchEventQueue::OnGestureScrollEvent(
void TouchEventQueue::FlushQueue() {
DCHECK(!dispatching_touch_ack_);
+ DCHECK(!dispatching_touch_);
while (!touch_queue_.empty())
- PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
- ui::LatencyInfo());
+ PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo());
+}
+
+bool TouchEventQueue::IsPendingAckTouchStart() const {
+ DCHECK(!dispatching_touch_ack_);
+ if (touch_queue_.empty())
+ return false;
+
+ const blink::WebTouchEvent& event =
+ touch_queue_.front()->coalesced_event().event;
+ return (event.type == WebInputEvent::TouchStart);
+}
+
+void TouchEventQueue::SetAckTimeoutEnabled(bool enabled,
+ size_t ack_timeout_delay_ms) {
+ if (!enabled) {
+ // Avoid resetting |timeout_handler_|, as an outstanding timeout may
+ // be active and must be completed for ack handling consistency.
+ ack_timeout_enabled_ = false;
+ return;
+ }
+
+ ack_timeout_enabled_ = true;
+ if (!timeout_handler_)
+ timeout_handler_.reset(new TouchTimeoutHandler(this, ack_timeout_delay_ms));
+}
+
+bool TouchEventQueue::HasTimeoutEvent() const {
+ return timeout_handler_ && timeout_handler_->HasTimeoutEvent();
}
-size_t TouchEventQueue::GetQueueSize() const {
- return touch_queue_.size();
+bool TouchEventQueue::IsTimeoutRunningForTesting() const {
+ return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning();
}
-const TouchEventWithLatencyInfo& TouchEventQueue::GetLatestEvent() const {
+const TouchEventWithLatencyInfo&
+TouchEventQueue::GetLatestEventForTesting() const {
return touch_queue_.back()->coalesced_event();
}
void TouchEventQueue::PopTouchEventToClient(
InputEventAckState ack_result,
const ui::LatencyInfo& renderer_latency_info) {
+ DCHECK(!dispatching_touch_ack_);
if (touch_queue_.empty())
return;
scoped_ptr<CoalescedWebTouchEvent> acked_event(touch_queue_.front());
@@ -234,19 +424,22 @@ void TouchEventQueue::PopTouchEventToClient(
}
bool TouchEventQueue::ShouldForwardToRenderer(
- const blink::WebTouchEvent& event) const {
+ const WebTouchEvent& event) const {
+ if (HasTimeoutEvent())
+ return false;
+
if (no_touch_to_renderer_ &&
event.type != blink::WebInputEvent::TouchCancel)
return false;
// Touch press events should always be forwarded to the renderer.
- if (event.type == blink::WebInputEvent::TouchStart)
+ if (event.type == WebInputEvent::TouchStart)
return true;
for (unsigned int i = 0; i < event.touchesLength; ++i) {
- const blink::WebTouchPoint& point = event.touches[i];
+ const WebTouchPoint& point = event.touches[i];
// If a point has been stationary, then don't take it into account.
- if (point.state == blink::WebTouchPoint::StateStationary)
+ if (point.state == WebTouchPoint::StateStationary)
continue;
if (touch_ack_states_.count(point.id) > 0) {
@@ -263,4 +456,25 @@ bool TouchEventQueue::ShouldForwardToRenderer(
return false;
}
+void TouchEventQueue::UpdateTouchAckStates(const WebTouchEvent& event,
+ InputEventAckState ack_result) {
+ // Update the ACK status for each touch point in the ACKed event.
+ if (event.type == WebInputEvent::TouchEnd ||
+ event.type == WebInputEvent::TouchCancel) {
+ // The points have been released. Erase the ACK states.
+ for (unsigned i = 0; i < event.touchesLength; ++i) {
+ const WebTouchPoint& point = event.touches[i];
+ if (point.state == WebTouchPoint::StateReleased ||
+ point.state == WebTouchPoint::StateCancelled)
+ touch_ack_states_.erase(point.id);
+ }
+ } else if (event.type == WebInputEvent::TouchStart) {
+ for (unsigned i = 0; i < event.touchesLength; ++i) {
+ const WebTouchPoint& point = event.touches[i];
+ if (point.state == WebTouchPoint::StatePressed)
+ touch_ack_states_[point.id] = ack_result;
+ }
+ }
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/touch_event_queue.h b/content/browser/renderer_host/input/touch_event_queue.h
index a3053c4e9b..ea7eb71fe5 100644
--- a/content/browser/renderer_host/input/touch_event_queue.h
+++ b/content/browser/renderer_host/input/touch_event_queue.h
@@ -38,7 +38,7 @@ class CONTENT_EXPORT TouchEventQueue {
// The |client| must outlive the TouchEventQueue.
explicit TouchEventQueue(TouchEventQueueClient* client);
- virtual ~TouchEventQueue();
+ ~TouchEventQueue();
// Adds an event to the queue. The event may be coalesced with previously
// queued events (e.g. consecutive touch-move events can be coalesced into a
@@ -54,28 +54,42 @@ class CONTENT_EXPORT TouchEventQueue {
// When GestureScrollBegin is received, we send a touch cancel to renderer,
// route all the following touch events directly to client, and ignore the
- // ack for the touch cancel. When GestureScrollEnd/GestureFlingStart is
- // received, we resume the normal flow of sending touch events to renderer.
+ // ack for the touch cancel. When Gesture{ScrollEnd,FlingStart} is received,
+ // resume the normal flow of sending touch events to the renderer.
void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event);
// Empties the queue of touch events. This may result in any number of gesture
// events being sent to the renderer.
void FlushQueue();
- // Returns whether the event-queue is empty.
+ // Returns whether the currently pending touch event (waiting ACK) is for
+ // a touch start event.
+ bool IsPendingAckTouchStart() const;
+
+ // Sets whether a delayed touch ack will cancel and flush the current
+ // touch sequence.
+ void SetAckTimeoutEnabled(bool enabled, size_t ack_timeout_delay_ms);
+
bool empty() const WARN_UNUSED_RESULT {
return touch_queue_.empty();
}
- bool no_touch_to_renderer() const {
- return no_touch_to_renderer_;
+ size_t size() const {
+ return touch_queue_.size();
+ }
+
+ bool ack_timeout_enabled() const {
+ return ack_timeout_enabled_;
}
private:
+ class TouchTimeoutHandler;
+ friend class TouchTimeoutHandler;
friend class TouchEventQueueTest;
- size_t GetQueueSize() const;
- const TouchEventWithLatencyInfo& GetLatestEvent() const;
+ bool HasTimeoutEvent() const;
+ bool IsTimeoutRunningForTesting() const;
+ const TouchEventWithLatencyInfo& GetLatestEventForTesting() const;
// Walks the queue, checking each event for |ShouldForwardToRenderer()|.
// If true, forwards the touch event and stops processing further events.
@@ -88,6 +102,10 @@ class CONTENT_EXPORT TouchEventQueue {
const ui::LatencyInfo& renderer_latency_info);
bool ShouldForwardToRenderer(const blink::WebTouchEvent& event) const;
+ void ForwardToRenderer(const TouchEventWithLatencyInfo& event);
+ void UpdateTouchAckStates(const blink::WebTouchEvent& event,
+ InputEventAckState ack_result);
+
// Handles touch event forwarding and ack'ed event dispatch.
TouchEventQueueClient* client_;
@@ -104,11 +122,21 @@ class CONTENT_EXPORT TouchEventQueue {
// is being dispatched.
CoalescedWebTouchEvent* dispatching_touch_ack_;
- // Don't send touch events to renderer. This is enabled when the page
- // is scrolling. This behaviour is currently enabled only on aura behind
- // a flag.
+ // Used to prevent touch timeout scheduling if we receive a synchronous
+ // ack after forwarding a touch event to the client.
+ bool dispatching_touch_;
+
+ // Don't send touch events to the renderer while scrolling.
bool no_touch_to_renderer_;
+ // Whether an event in the current (multi)touch sequence was consumed by the
+ // renderer. The touch timeout will never be activated when this is true.
+ bool renderer_is_consuming_touch_gesture_;
+
+ // Optional handler for timed-out touch event acks, disabled by default.
+ bool ack_timeout_enabled_;
+ scoped_ptr<TouchTimeoutHandler> timeout_handler_;
+
DISALLOW_COPY_AND_ASSIGN(TouchEventQueue);
};
diff --git a/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
index b4631b9858..875b798546 100644
--- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
@@ -5,8 +5,10 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/renderer_host/input/timeout_monitor.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -16,6 +18,9 @@ using blink::WebTouchEvent;
using blink::WebTouchPoint;
namespace content {
+namespace {
+const size_t kDefaultTouchTimeoutDelayMs = 10;
+}
class TouchEventQueueTest : public testing::Test,
public TouchEventQueueClient {
@@ -67,13 +72,12 @@ class TouchEventQueueTest : public testing::Test,
protected:
- void SendTouchEvent(const WebTouchEvent& event) {
- queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo()));
+ void SetUpForTimeoutTesting(size_t timeout_delay_ms) {
+ queue_->SetAckTimeoutEnabled(true, timeout_delay_ms);
}
- void SendTouchEvent() {
- SendTouchEvent(touch_event_);
- touch_event_.ResetPoints();
+ void SendTouchEvent(const WebTouchEvent& event) {
+ queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo()));
}
void SendGestureEvent(WebInputEvent::Type type) {
@@ -99,20 +103,30 @@ class TouchEventQueueTest : public testing::Test,
sync_ack_result_.reset(new InputEventAckState(sync_ack_result));
}
- int PressTouchPoint(int x, int y) {
- return touch_event_.PressPoint(x, y);
+ void PressTouchPoint(int x, int y) {
+ touch_event_.PressPoint(x, y);
+ SendTouchEvent();
}
void MoveTouchPoint(int index, int x, int y) {
touch_event_.MovePoint(index, x, y);
+ SendTouchEvent();
+ }
+
+ void MoveTouchPoints(int index0, int x0, int y0, int index1, int x1, int y1) {
+ touch_event_.MovePoint(index0, x0, y0);
+ touch_event_.MovePoint(index1, x1, y1);
+ SendTouchEvent();
}
void ReleaseTouchPoint(int index) {
touch_event_.ReleasePoint(index);
+ SendTouchEvent();
}
void CancelTouchPoint(int index) {
touch_event_.CancelPoint(index);
+ SendTouchEvent();
}
size_t GetAndResetAckedEventCount() {
@@ -127,16 +141,32 @@ class TouchEventQueueTest : public testing::Test,
return count;
}
+ bool IsPendingAckTouchStart() const {
+ return queue_->IsPendingAckTouchStart();
+ }
+
void Flush() {
queue_->FlushQueue();
}
+ void SetEnableTouchForwarding(bool enabled) {
+ queue_->no_touch_to_renderer_ = !enabled;
+ }
+
+ bool WillForwardTouchEvents() {
+ return !queue_->no_touch_to_renderer_ && !queue_->HasTimeoutEvent();
+ }
+
+ bool IsTimeoutRunning() {
+ return queue_->IsTimeoutRunningForTesting();
+ }
+
size_t queued_event_count() const {
- return queue_->GetQueueSize();
+ return queue_->size();
}
const WebTouchEvent& latest_event() const {
- return queue_->GetLatestEvent().event;
+ return queue_->GetLatestEventForTesting().event;
}
const WebTouchEvent& acked_event() const {
@@ -160,6 +190,11 @@ class TouchEventQueueTest : public testing::Test,
}
private:
+ void SendTouchEvent() {
+ SendTouchEvent(touch_event_);
+ touch_event_.ResetPoints();
+ }
+
scoped_ptr<TouchEventQueue> queue_;
size_t sent_event_count_;
size_t acked_event_count_;
@@ -170,19 +205,18 @@ class TouchEventQueueTest : public testing::Test,
scoped_ptr<WebTouchEvent> followup_touch_event_;
scoped_ptr<WebGestureEvent> followup_gesture_event_;
scoped_ptr<InputEventAckState> sync_ack_result_;
+ base::MessageLoopForUI message_loop_;
};
// Tests that touch-events are queued properly.
TEST_F(TouchEventQueueTest, Basic) {
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
// The second touch should not be sent since one is already in queue.
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
@@ -210,20 +244,15 @@ TEST_F(TouchEventQueueTest, Flush) {
// Send a touch-press event.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
ReleaseTouchPoint(0);
- SendTouchEvent();
// Events will be queued until the first sent event is ack'ed.
for (int i = 5; i < 15; ++i) {
PressTouchPoint(1, 1);
- SendTouchEvent();
MoveTouchPoint(0, i, i);
- SendTouchEvent();
ReleaseTouchPoint(0);
- SendTouchEvent();
}
EXPECT_EQ(32U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
@@ -248,18 +277,15 @@ TEST_F(TouchEventQueueTest, Flush) {
TEST_F(TouchEventQueueTest, Coalesce) {
// Send a touch-press event.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
// Send a few touch-move events, followed by a touch-release event. All the
// touch-move events should be coalesced into a single event.
- for (int i = 5; i < 15; ++i) {
+ for (int i = 5; i < 15; ++i)
MoveTouchPoint(0, i, i);
- SendTouchEvent();
- }
+
EXPECT_EQ(0U, GetAndResetSentEventCount());
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(3U, queued_event_count());
@@ -291,15 +317,13 @@ TEST_F(TouchEventQueueTest, Coalesce) {
TEST_F(TouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
// Send a touch-press event.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
// Send a few touch-move events, followed by a touch-release event. All the
// touch-move events should be coalesced into a single event.
- for (int i = 5; i < 15; ++i) {
+ for (int i = 5; i < 15; ++i)
MoveTouchPoint(0, i, i);
- SendTouchEvent();
- }
+
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
@@ -310,11 +334,9 @@ TEST_F(TouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
// The coalesced touch-move event has been sent to the renderer. Any new
// touch-move event should not be coalesced with the sent event.
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
MoveTouchPoint(0, 7, 7);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
}
@@ -322,33 +344,27 @@ TEST_F(TouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
TEST_F(TouchEventQueueTest, MultiTouch) {
// Press the first finger.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
// Move the finger.
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
// Now press a second finger.
PressTouchPoint(2, 2);
- SendTouchEvent();
EXPECT_EQ(3U, queued_event_count());
// Move both fingers.
- MoveTouchPoint(0, 10, 10);
+ MoveTouchPoints(0, 10, 10, 1, 20, 20);
MoveTouchPoint(1, 20, 20);
- SendTouchEvent();
EXPECT_EQ(4U, queued_event_count());
// Move only one finger now.
MoveTouchPoint(0, 15, 15);
- SendTouchEvent();
EXPECT_EQ(4U, queued_event_count());
// Move the other finger.
MoveTouchPoint(1, 25, 25);
- SendTouchEvent();
EXPECT_EQ(4U, queued_event_count());
// Make sure both fingers are marked as having been moved in the coalesced
@@ -364,12 +380,10 @@ TEST_F(TouchEventQueueTest, MultiTouch) {
TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) {
// Send some touch-events to the renderer.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
MoveTouchPoint(0, 10, 10);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
@@ -397,12 +411,10 @@ TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) {
TEST_F(TouchEventQueueTest, NoConsumer) {
// The first touch-press should reach the renderer.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
// The second touch should not be sent since one is already in queue.
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
@@ -416,7 +428,6 @@ TEST_F(TouchEventQueueTest, NoConsumer) {
// Send a release event. This should not reach the renderer.
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
@@ -426,18 +437,13 @@ TEST_F(TouchEventQueueTest, NoConsumer) {
// events should be queued first. After the NO_CONSUMER ack for the first
// touch-press, all events upto the second touch-press should be flushed.
PressTouchPoint(10, 10);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
MoveTouchPoint(0, 6, 5);
- SendTouchEvent();
ReleaseTouchPoint(0);
- SendTouchEvent();
PressTouchPoint(6, 5);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
// The queue should hold the first sent touch-press event, the coalesced
// touch-move event, the touch-end event and the second touch-press event.
@@ -459,7 +465,6 @@ TEST_F(TouchEventQueueTest, NoConsumer) {
// Send a second press event. Even though the first touch had NO_CONSUMER,
// this press event should reach the renderer.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
}
@@ -470,24 +475,17 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
// the second touch point.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
MoveTouchPoint(0, 5, 5);
- SendTouchEvent();
PressTouchPoint(10, 10);
- SendTouchEvent();
MoveTouchPoint(0, 2, 2);
- SendTouchEvent();
MoveTouchPoint(1, 4, 10);
- SendTouchEvent();
- MoveTouchPoint(0, 10, 10);
- MoveTouchPoint(1, 20, 20);
- SendTouchEvent();
+ MoveTouchPoints(0, 10, 10, 1, 20, 20);
// Since the first touch-press is still pending ACK, no other event should
// have been sent to the renderer.
@@ -523,22 +521,18 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
// Move just the second touch point. Because the first touch point did not
// move, this event should not reach the renderer.
MoveTouchPoint(1, 30, 30);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count());
// Move just the first touch point. This should reach the renderer.
MoveTouchPoint(0, 10, 10);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
// Move both fingers. This event should reach the renderer (after the ACK of
// the previous move event is received), because the first touch point did
// move.
- MoveTouchPoint(0, 15, 15);
- MoveTouchPoint(1, 25, 25);
- SendTouchEvent();
+ MoveTouchPoints(0, 15, 15, 1, 25, 25);
EXPECT_EQ(0U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -554,21 +548,16 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
// the second finger should be immediately released to the view, and the
// touch-press event should be dispatched to the renderer.
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
MoveTouchPoint(1, 40, 40);
- SendTouchEvent();
MoveTouchPoint(1, 50, 50);
- SendTouchEvent();
PressTouchPoint(1, 1);
- SendTouchEvent();
MoveTouchPoint(1, 30, 30);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(4U, queued_event_count());
@@ -594,7 +583,6 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
TEST_F(TouchEventQueueTest, AckWithFollowupEvents) {
// Queue a touch down.
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
@@ -618,9 +606,7 @@ TEST_F(TouchEventQueueTest, AckWithFollowupEvents) {
EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type);
// Queue another event.
- PressTouchPoint(1, 1);
MoveTouchPoint(0, 2, 2);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
// Receive an ACK for the touch-move followup event. This should cause the
@@ -636,41 +622,33 @@ TEST_F(TouchEventQueueTest, SynchronousAcks) {
// TouchStart
SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
PressTouchPoint(1, 1);
- SendTouchEvent();
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchMove
SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- PressTouchPoint(1, 1);
MoveTouchPoint(0, 2, 2);
- SendTouchEvent();
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchEnd
SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- PressTouchPoint(1, 1);
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchCancel (first inserting a TouchStart so the TouchCancel will be sent)
PressTouchPoint(1, 1);
- SendTouchEvent();
SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- PressTouchPoint(1, 1);
CancelTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
@@ -707,47 +685,40 @@ TEST_F(TouchEventQueueTest, ImmediateAckWithFollowupEvents) {
// Tests basic TouchEvent forwarding suppression.
TEST_F(TouchEventQueueTest, NoTouchBasic) {
// Disable TouchEvent forwarding.
- set_no_touch_to_renderer(true);
+ SetEnableTouchForwarding(false);
MoveTouchPoint(0, 30, 5);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchMove should not be sent to renderer.
MoveTouchPoint(0, 65, 10);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchEnd should not be sent to renderer.
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchStart should not be sent to renderer.
PressTouchPoint(5, 5);
- SendTouchEvent();
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Enable TouchEvent forwarding.
- set_no_touch_to_renderer(false);
+ SetEnableTouchForwarding(true);
PressTouchPoint(80, 10);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 80, 20);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
@@ -757,19 +728,16 @@ TEST_F(TouchEventQueueTest, NoTouchBasic) {
TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
// Queue a TouchStart.
PressTouchPoint(0, 1);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 20, 5);
- SendTouchEvent();
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
// Queue another TouchStart.
PressTouchPoint(20, 20);
- SendTouchEvent();
EXPECT_EQ(2U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type);
@@ -778,9 +746,9 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
WebGestureEvent followup_scroll;
followup_scroll.type = WebInputEvent::GestureScrollBegin;
SetFollowupEvent(followup_scroll);
- ASSERT_FALSE(no_touch_to_renderer());
+ ASSERT_TRUE(WillForwardTouchEvents());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(no_touch_to_renderer());
+ EXPECT_FALSE(WillForwardTouchEvents());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(2U, queued_event_count());
@@ -794,46 +762,387 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type);
- // TouchMove should not be sent to renderer.
+ // TouchMove should not be sent to the renderer.
MoveTouchPoint(0, 30, 5);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
// GestureScrollUpdates should not change affect touch forwarding.
SendGestureEvent(WebInputEvent::GestureScrollUpdate);
- EXPECT_TRUE(no_touch_to_renderer());
+ EXPECT_FALSE(WillForwardTouchEvents());
- // TouchEnd should not be sent to renderer.
+ // TouchEnd should not be sent to the renderer.
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
// GestureScrollEnd will resume the sending of TouchEvents to renderer.
SendGestureEvent(blink::WebInputEvent::GestureScrollEnd);
- EXPECT_FALSE(no_touch_to_renderer());
+ EXPECT_TRUE(WillForwardTouchEvents());
// Now TouchEvents should be forwarded normally.
PressTouchPoint(80, 10);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 80, 20);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
ReleaseTouchPoint(0);
- SendTouchEvent();
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
}
+// Tests that IsTouchStartPendingAck works correctly.
+TEST_F(TouchEventQueueTest, PendingStart) {
+
+ EXPECT_FALSE(IsPendingAckTouchStart());
+
+ // Send the touchstart for one point (#1).
+ PressTouchPoint(1, 1);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_TRUE(IsPendingAckTouchStart());
+
+ // Send a touchmove for that point (#2).
+ MoveTouchPoint(0, 5, 5);
+ EXPECT_EQ(2U, queued_event_count());
+ EXPECT_TRUE(IsPendingAckTouchStart());
+
+ // Ack the touchstart (#1).
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_FALSE(IsPendingAckTouchStart());
+
+ // Send a touchstart for another point (#3).
+ PressTouchPoint(10, 10);
+ EXPECT_EQ(2U, queued_event_count());
+ EXPECT_FALSE(IsPendingAckTouchStart());
+
+ // Ack the touchmove (#2).
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_TRUE(IsPendingAckTouchStart());
+
+ // Send a touchstart for a third point (#4).
+ PressTouchPoint(15, 15);
+ EXPECT_EQ(2U, queued_event_count());
+ EXPECT_TRUE(IsPendingAckTouchStart());
+
+ // Ack the touchstart for the second point (#3).
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_TRUE(IsPendingAckTouchStart());
+
+ // Ack the touchstart for the third point (#4).
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_FALSE(IsPendingAckTouchStart());
+}
+
+// Tests that the touch timeout is started when sending certain touch types.
+TEST_F(TouchEventQueueTest, TouchTimeoutTypes) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Sending a TouchStart will start the timeout.
+ PressTouchPoint(0, 1);
+ EXPECT_TRUE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+
+ // A TouchMove should start the timeout.
+ MoveTouchPoint(0, 5, 5);
+ EXPECT_TRUE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+
+ // A TouchEnd should not start the timeout.
+ ReleaseTouchPoint(0);
+ EXPECT_FALSE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+
+ // A TouchCancel should not start the timeout.
+ PressTouchPoint(0, 1);
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_FALSE(IsTimeoutRunning());
+ CancelTouchPoint(0);
+ EXPECT_FALSE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+}
+
+// Tests that a delayed TouchEvent ack will trigger a TouchCancel timeout,
+// disabling touch forwarding until the next TouchStart is received after
+// the timeout events are ack'ed.
+TEST_F(TouchEventQueueTest, TouchTimeoutBasic) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ GetAndResetSentEventCount();
+ GetAndResetAckedEventCount();
+ PressTouchPoint(0, 1);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(0U, GetAndResetAckedEventCount());
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_TRUE(WillForwardTouchEvents());
+
+ // Delay the ack.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ base::TimeDelta::FromMilliseconds(kDefaultTouchTimeoutDelayMs * 2));
+ base::MessageLoop::current()->Run();
+
+ // The timeout should have fired, synthetically ack'ing the timed-out event.
+ // TouchEvent forwarding is disabled until the ack is received for the
+ // timed-out event and the future cancel event.
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Ack'ing the original event should trigger a cancel event.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+
+ // Touch events should not be forwarded until we receive the cancel acks.
+ PressTouchPoint(0, 1);
+ ASSERT_EQ(0U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // The synthetic TouchCancel ack should not reach the client, but should
+ // resume touch forwarding.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+ EXPECT_TRUE(WillForwardTouchEvents());
+
+ // Subsequent events should be handled normally.
+ PressTouchPoint(0, 1);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+// Tests that the timeout is never started if the renderer consumes
+// a TouchEvent from the current touch sequence.
+TEST_F(TouchEventQueueTest, NoTouchTimeoutIfRendererIsConsumingGesture) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ ASSERT_TRUE(IsTimeoutRunning());
+
+ // Mark the event as consumed. This should prevent the timeout from
+ // being activated on subsequent TouchEvents in this gesture.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+
+ // A TouchMove should not start the timeout.
+ MoveTouchPoint(0, 5, 5);
+ EXPECT_FALSE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ // A secondary TouchStart should not start the timeout.
+ PressTouchPoint(1, 0);
+ EXPECT_FALSE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ // A TouchEnd should not start the timeout.
+ ReleaseTouchPoint(1);
+ EXPECT_FALSE(IsTimeoutRunning());
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ // A TouchCancel should not start the timeout.
+ CancelTouchPoint(0);
+ EXPECT_FALSE(IsTimeoutRunning());
+}
+
+// Tests that the timeout is never started if the ack is synchronous.
+TEST_F(TouchEventQueueTest, NoTouchTimeoutIfAckIsSynchronous) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
+ ASSERT_FALSE(IsTimeoutRunning());
+ PressTouchPoint(0, 1);
+ EXPECT_FALSE(IsTimeoutRunning());
+}
+
+// Tests that a TouchCancel timeout plays nice when the timed out touch stream
+// turns into a scroll gesture sequence.
+TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGesture) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_TRUE(WillForwardTouchEvents());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+
+ // The cancelled sequence may turn into a scroll gesture.
+ WebGestureEvent followup_scroll;
+ followup_scroll.type = WebInputEvent::GestureScrollBegin;
+ SetFollowupEvent(followup_scroll);
+
+ // Delay the ack.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ base::TimeDelta::FromMilliseconds(kDefaultTouchTimeoutDelayMs * 2));
+ base::MessageLoop::current()->Run();
+
+ // The timeout should have fired, disabling touch forwarding until both acks
+ // are received, acking the timed out event.
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Ack the original event, triggering a TouchCancel.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+
+ // Ack the cancel event. Normally, this would resume touch forwarding,
+ // but we're still within a scroll gesture so it remains disabled.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+
+ // Try to forward a touch event.
+ GetAndResetSentEventCount();
+ GetAndResetAckedEventCount();
+ PressTouchPoint(0, 1);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Now end the scroll sequence, resuming touch handling.
+ SendGestureEvent(blink::WebInputEvent::GestureScrollEnd);
+ EXPECT_TRUE(WillForwardTouchEvents());
+ PressTouchPoint(0, 1);
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+// Tests that a TouchCancel timeout plays nice when the timed out touch stream
+// turns into a scroll gesture sequence, but the original event acks are
+// significantly delayed.
+TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGestureAndDelayedAck) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_TRUE(WillForwardTouchEvents());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+
+ // The cancelled sequence may turn into a scroll gesture.
+ WebGestureEvent followup_scroll;
+ followup_scroll.type = WebInputEvent::GestureScrollBegin;
+ SetFollowupEvent(followup_scroll);
+
+ // Delay the ack.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ base::TimeDelta::FromMilliseconds(kDefaultTouchTimeoutDelayMs * 2));
+ base::MessageLoop::current()->Run();
+
+ // The timeout should have fired, disabling touch forwarding until both acks
+ // are received and acking the timed out event.
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Try to forward a touch event.
+ GetAndResetSentEventCount();
+ GetAndResetAckedEventCount();
+ PressTouchPoint(0, 1);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Now end the scroll sequence. Events will not be forwarded until the two
+ // outstanding touch acks are received.
+ SendGestureEvent(blink::WebInputEvent::GestureScrollEnd);
+ PressTouchPoint(0, 1);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Ack the original event, triggering a cancel.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+
+ // Ack the cancel event, resuming touch forwarding.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+
+ PressTouchPoint(0, 1);
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+}
+
+// Tests that a delayed TouchEvent ack will not trigger a TouchCancel timeout if
+// the timed-out event had no consumer.
+TEST_F(TouchEventQueueTest, NoCancelOnTouchTimeoutWithoutConsumer) {
+ SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(0U, GetAndResetAckedEventCount());
+ EXPECT_TRUE(IsTimeoutRunning());
+ EXPECT_TRUE(WillForwardTouchEvents());
+
+ // Delay the ack.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ base::TimeDelta::FromMilliseconds(kDefaultTouchTimeoutDelayMs * 2));
+ base::MessageLoop::current()->Run();
+
+ // The timeout should have fired, synthetically ack'ing the timed out event.
+ // TouchEvent forwarding is disabled until the original ack is received.
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_FALSE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Touch events should not be forwarded until we receive the original ack.
+ PressTouchPoint(0, 1);
+ ASSERT_EQ(0U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Ack'ing the original event should not trigger a cancel event, as the
+ // TouchStart had no consumer. However, it should re-enable touch forwarding.
+ SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ EXPECT_FALSE(IsTimeoutRunning());
+ EXPECT_TRUE(WillForwardTouchEvents());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+
+ // Subsequent events should be handled normally.
+ PressTouchPoint(0, 1);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
} // namespace content
diff --git a/content/browser/renderer_host/input/touch_input_browsertest.cc b/content/browser/renderer_host/input/touch_input_browsertest.cc
new file mode 100644
index 0000000000..859e1a4af4
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_input_browsertest.cc
@@ -0,0 +1,307 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/auto_reset.h"
+#include "base/command_line.h"
+#include "base/run_loop.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+#include "content/common/input_messages.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/common/content_switches.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/events/event_switches.h"
+#include "ui/events/latency_info.h"
+
+using blink::WebInputEvent;
+
+namespace {
+
+void GiveItSomeTime() {
+ base::RunLoop run_loop;
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(10));
+ run_loop.Run();
+}
+
+const char kTouchEventDataURL[] =
+ "data:text/html;charset=utf-8,"
+ "<body onload='setup();'>"
+ "<div id='first'></div><div id='second'></div><div id='third'></div>"
+ "<style>"
+ " #first {"
+ " position: absolute;"
+ " width: 100px;"
+ " height: 100px;"
+ " top: 0px;"
+ " left: 0px;"
+ " background-color: green;"
+ " -webkit-transform: translate3d(0, 0, 0);"
+ " }"
+ " #second {"
+ " position: absolute;"
+ " width: 100px;"
+ " height: 100px;"
+ " top: 0px;"
+ " left: 110px;"
+ " background-color: blue;"
+ " -webkit-transform: translate3d(0, 0, 0);"
+ " }"
+ " #third {"
+ " position: absolute;"
+ " width: 100px;"
+ " height: 100px;"
+ " top: 110px;"
+ " left: 0px;"
+ " background-color: yellow;"
+ " -webkit-transform: translate3d(0, 0, 0);"
+ " }"
+ "</style>"
+ "<script>"
+ " function setup() {"
+ " second.ontouchstart = function() {};"
+ " third.ontouchstart = function(e) {"
+ " e.preventDefault();"
+ " };"
+ " }"
+ "</script>";
+
+} // namespace
+
+namespace content {
+
+class InputEventMessageFilter : public BrowserMessageFilter {
+ public:
+ InputEventMessageFilter()
+ : type_(WebInputEvent::Undefined),
+ state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
+
+ void WaitForAck(WebInputEvent::Type type) {
+ base::RunLoop run_loop;
+ base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
+ base::AutoReset<WebInputEvent::Type> reset_type(&type_, type);
+ run_loop.Run();
+ }
+
+ InputEventAckState last_ack_state() const { return state_; }
+
+ protected:
+ virtual ~InputEventMessageFilter() {}
+
+ private:
+ void ReceivedEventAck(WebInputEvent::Type type, InputEventAckState state) {
+ if (type_ == type) {
+ state_ = state;
+ quit_.Run();
+ }
+ }
+
+ // BrowserMessageFilter:
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE {
+ if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) {
+ ui::LatencyInfo latency;
+ WebInputEvent::Type type = WebInputEvent::Undefined;
+ InputEventAckState ack = INPUT_EVENT_ACK_STATE_UNKNOWN;
+ InputHostMsg_HandleInputEvent_ACK::Read(&message, &type, &ack, &latency);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&InputEventMessageFilter::ReceivedEventAck,
+ this, type, ack));
+ }
+ return false;
+ }
+
+ base::Closure quit_;
+ WebInputEvent::Type type_;
+ InputEventAckState state_;
+
+ DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilter);
+};
+
+class TouchInputBrowserTest : public ContentBrowserTest,
+ public testing::WithParamInterface<std::string> {
+ public:
+ TouchInputBrowserTest() {}
+ virtual ~TouchInputBrowserTest() {}
+
+ RenderWidgetHostImpl* GetWidgetHost() {
+ return RenderWidgetHostImpl::From(shell()->web_contents()->
+ GetRenderViewHost());
+ }
+
+ InputEventMessageFilter* filter() { return filter_.get(); }
+
+ protected:
+ void LoadURLAndAddFilter() {
+ const GURL data_url(kTouchEventDataURL);
+ NavigateToURL(shell(), data_url);
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderWidgetHostImpl* host =
+ RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
+ host->GetView()->SetSize(gfx::Size(400, 400));
+
+ // The page is loaded in the renderer, wait for a new frame to arrive.
+ while (!host->ScheduleComposite())
+ GiveItSomeTime();
+
+ filter_ = new InputEventMessageFilter();
+ host->GetProcess()->AddFilter(filter_);
+ }
+
+ // ContentBrowserTest:
+ virtual void SetUp() OVERRIDE {
+ // We expect real pixel output for these tests.
+ UseRealGLContexts();
+
+ // On legacy windows, these tests need real GL bindings to pass.
+#if defined(OS_WIN) && !defined(USE_AURA)
+ UseRealGLBindings();
+#endif
+
+ ContentBrowserTest::SetUp();
+ }
+
+ virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
+ cmd->AppendSwitchASCII(switches::kTouchEvents,
+ switches::kTouchEventsEnabled);
+ cmd->AppendSwitch(GetParam());
+ }
+
+ scoped_refptr<InputEventMessageFilter> filter_;
+};
+
+// Touch input event tests don't work on Mac with the legacy software renderer.
+// These can be enabled when software compositing is enabled.
+// http://crbug.com/268038
+#if defined(OS_MACOSX)
+#define MAYBE_TouchNoHandler DISABLED_TouchNoHandler
+#else
+#define MAYBE_TouchNoHandler TouchNoHandler
+#endif
+IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchNoHandler) {
+ LoadURLAndAddFilter();
+ SyntheticWebTouchEvent touch;
+
+ // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is
+ // no touch-handler on it.
+ touch.PressPoint(25, 25);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchStart);
+
+ if (GetParam() == std::string(switches::kEnableThreadedCompositing)) {
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
+ filter()->last_ack_state());
+ } else {
+ // http://crbug.com/326232: This should be NO_CONSUMER_EXISTS once
+ // WebViewImpl::hasTouchEventHandlersAt() is implemented.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
+ }
+
+ // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent
+ // touch-points don't need to be dispatched until the touch point is released.
+ touch.ReleasePoint(0);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ touch.ResetPoints();
+}
+
+// Touch input event tests don't work on Mac with the legacy software renderer.
+// These can be enabled when software compositing is enabled.
+// http://crbug.com/268038
+#if defined(OS_MACOSX)
+#define MAYBE_TouchHandlerNoConsume DISABLED_TouchHandlerNoConsume
+#else
+#define MAYBE_TouchHandlerNoConsume TouchHandlerNoConsume
+#endif
+IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) {
+ LoadURLAndAddFilter();
+ SyntheticWebTouchEvent touch;
+
+ // Press on |second| should be acked with NOT_CONSUMED since there is a
+ // touch-handler on |second|, but it doesn't consume the event.
+ touch.PressPoint(125, 25);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchStart);
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
+
+ touch.ReleasePoint(0);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchEnd);
+ touch.ResetPoints();
+}
+
+// Touch input event tests don't work on Mac with the legacy software renderer.
+// These can be enabled when software compositing is enabled.
+// http://crbug.com/268038
+#if defined(OS_MACOSX)
+#define MAYBE_TouchHandlerConsume DISABLED_TouchHandlerConsume
+#else
+#define MAYBE_TouchHandlerConsume TouchHandlerConsume
+#endif
+IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) {
+ LoadURLAndAddFilter();
+ SyntheticWebTouchEvent touch;
+
+ // Press on |third| should be acked with CONSUMED since the touch-handler on
+ // |third| consimes the event.
+ touch.PressPoint(25, 125);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchStart);
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
+
+ touch.ReleasePoint(0);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchEnd);
+}
+
+// Touch input event tests don't work on Mac with the legacy software renderer.
+// These can be enabled when software compositing is enabled.
+// http://crbug.com/268038
+#if defined(OS_MACOSX)
+#define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress
+#else
+#define MAYBE_MultiPointTouchPress MultiPointTouchPress
+#endif
+IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) {
+ LoadURLAndAddFilter();
+ SyntheticWebTouchEvent touch;
+
+ // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press
+ // on |third|. That point should be acked with CONSUMED.
+ touch.PressPoint(25, 25);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchStart);
+ if (GetParam() == std::string(switches::kEnableThreadedCompositing)) {
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
+ filter()->last_ack_state());
+ } else {
+ // http://crbug.com/326232: This should be NO_CONSUMER_EXISTS once
+ // WebViewImpl::hasTouchEventHandlersAt() is implemented.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
+ }
+
+ touch.PressPoint(25, 125);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
+ filter()->WaitForAck(WebInputEvent::TouchStart);
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
+}
+
+INSTANTIATE_TEST_CASE_P(WithoutInputHandlerProxy, TouchInputBrowserTest,
+ ::testing::Values(std::string(switches::kDisableThreadedCompositing)));
+
+#if !defined(OS_MACOSX)
+INSTANTIATE_TEST_CASE_P(WithInputHandlerProxy, TouchInputBrowserTest,
+ ::testing::Values(std::string(switches::kEnableThreadedCompositing)));
+#endif
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
index bbb6a08c2f..39fca2f854 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
@@ -9,7 +9,7 @@
#include "ui/events/gestures/gesture_configuration.h"
#if defined(OS_ANDROID)
-#include "content/common/android/view_configuration.h"
+#include "ui/gfx/android/view_configuration.h"
#endif
namespace content {
@@ -56,11 +56,11 @@ bool TouchscreenTapSuppressionController::ShouldSuppressGestureTapEnd() {
// TODO(jdduke): Enable ui::GestureConfiguration on Android and initialize
// with parameters from ViewConfiguration.
int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
- return ViewConfiguration::GetTapTimeoutInMs();
+ return gfx::ViewConfiguration::GetTapTimeoutInMs();
}
int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
- return ViewConfiguration::GetLongPressTimeoutInMs();
+ return gfx::ViewConfiguration::GetLongPressTimeoutInMs();
}
#else
int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
diff --git a/content/browser/renderer_host/java/OWNERS b/content/browser/renderer_host/java/OWNERS
index 4b297c43ee..d378671071 100644
--- a/content/browser/renderer_host/java/OWNERS
+++ b/content/browser/renderer_host/java/OWNERS
@@ -1,2 +1,2 @@
-joth@chromium.org
steveblock@chromium.org
+torne@chromium.org
diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
index 6d792e7dac..562517a114 100644
--- a/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
+++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host.cc
@@ -59,7 +59,7 @@ JavaBridgeDispatcherHost::~JavaBridgeDispatcherHost() {
base::Bind(&CleanUpStubs, stubs_));
}
-void JavaBridgeDispatcherHost::AddNamedObject(const string16& name,
+void JavaBridgeDispatcherHost::AddNamedObject(const base::string16& name,
NPObject* object) {
NPVariant_Param variant_param;
CreateNPVariantParam(object, &variant_param);
@@ -68,7 +68,7 @@ void JavaBridgeDispatcherHost::AddNamedObject(const string16& name,
render_view_host_->GetRoutingID(), name, variant_param));
}
-void JavaBridgeDispatcherHost::RemoveNamedObject(const string16& name) {
+void JavaBridgeDispatcherHost::RemoveNamedObject(const base::string16& name) {
// On receipt of this message, the JavaBridgeDispatcher will drop its
// reference to the corresponding proxy object. When the last reference is
// removed, the proxy object will delete its NPObjectProxy, which will cause
diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host.h b/content/browser/renderer_host/java/java_bridge_dispatcher_host.h
index 94ee632131..21e47c0d3b 100644
--- a/content/browser/renderer_host/java/java_bridge_dispatcher_host.h
+++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host.h
@@ -42,8 +42,8 @@ class JavaBridgeDispatcherHost
// to |object|, which is manipulated on the background thread. This class
// holds a reference to |object| for the time that the proxy object is bound
// to the window object.
- void AddNamedObject(const string16& name, NPObject* object);
- void RemoveNamedObject(const string16& name);
+ void AddNamedObject(const base::string16& name, NPObject* object);
+ void RemoveNamedObject(const base::string16& name);
// Since this object is ref-counted, it might outlive render_view_host_.
void RenderViewDeleted();
diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc b/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc
index f06d9fe4aa..02cf4dcc06 100644
--- a/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc
+++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.cc
@@ -31,7 +31,7 @@ JavaBridgeDispatcherHostManager::~JavaBridgeDispatcherHostManager() {
DCHECK_EQ(0U, instances_.size());
}
-void JavaBridgeDispatcherHostManager::AddNamedObject(const string16& name,
+void JavaBridgeDispatcherHostManager::AddNamedObject(const base::string16& name,
NPObject* object) {
// Record this object in a map so that we can add it into RenderViewHosts
// created later. The JavaBridgeDispatcherHost instances will take a
@@ -67,7 +67,8 @@ void JavaBridgeDispatcherHostManager::SetRetainedObjectSet(
}
}
-void JavaBridgeDispatcherHostManager::RemoveNamedObject(const string16& name) {
+void JavaBridgeDispatcherHostManager::RemoveNamedObject(
+ const base::string16& name) {
ObjectMap::iterator iter = objects_.find(name);
if (iter == objects_.end()) {
return;
diff --git a/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h b/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h
index e3d629af37..29523b5739 100644
--- a/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h
+++ b/content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h
@@ -34,8 +34,8 @@ class JavaBridgeDispatcherHostManager
// These methods add or remove the object to each JavaBridgeDispatcherHost.
// Each one holds a reference to the NPObject while the object is bound to
// the corresponding RenderView. See JavaBridgeDispatcherHost for details.
- void AddNamedObject(const string16& name, NPObject* object);
- void RemoveNamedObject(const string16& name);
+ void AddNamedObject(const base::string16& name, NPObject* object);
+ void RemoveNamedObject(const base::string16& name);
void OnGetChannelHandle(RenderViewHost* render_view_host,
IPC::Message* reply_msg);
@@ -60,7 +60,7 @@ class JavaBridgeDispatcherHostManager
typedef std::map<RenderViewHost*, scoped_refptr<JavaBridgeDispatcherHost> >
InstanceMap;
InstanceMap instances_;
- typedef std::map<string16, NPObject*> ObjectMap;
+ typedef std::map<base::string16, NPObject*> ObjectMap;
ObjectMap objects_;
JavaObjectWeakGlobalRef retained_object_set_;
diff --git a/content/browser/renderer_host/java/java_method.cc b/content/browser/renderer_host/java/java_method.cc
index ef2d097dd3..5a654fe130 100644
--- a/content/browser/renderer_host/java/java_method.cc
+++ b/content/browser/renderer_host/java/java_method.cc
@@ -86,7 +86,7 @@ std::string BinaryNameToJNIName(const std::string& binary_name,
return jni_name;
}
NOTREACHED();
- return EmptyString();
+ return std::string();
}
} // namespace
diff --git a/content/browser/renderer_host/media/OWNERS b/content/browser/renderer_host/media/OWNERS
index 45ac661112..bc20fb9af2 100644
--- a/content/browser/renderer_host/media/OWNERS
+++ b/content/browser/renderer_host/media/OWNERS
@@ -16,6 +16,9 @@ per-file web_contents*=hclam@chromium.org
per-file web_contents*=justinlin@chromium.org
per-file web_contents*=miu@chromium.org
per-file web_contents*=nick@chromium.org
+per-file video_capture_device_impl*=hclam@chromium.org
+per-file video_capture_device_impl*=miu@chromium.org
+per-file video_capture_device_impl*=nick@chromium.org
per-file video_capture_oracle*=hclam@chromium.org
per-file video_capture_oracle*=justinlin@chromium.org
per-file video_capture_oracle*=miu@chromium.org
diff --git a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
index a94d7f1c36..76cb1794a9 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
@@ -55,7 +55,7 @@ class AudioInputDeviceManagerTest : public testing::Test {
message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
message_loop_.get()));
- audio_manager_.reset(media::AudioManager::Create());
+ audio_manager_.reset(media::AudioManager::CreateForTesting());
manager_ = new AudioInputDeviceManager(audio_manager_.get());
audio_input_listener_.reset(new MockAudioInputDeviceManagerListener());
manager_->Register(audio_input_listener_.get(),
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 0f8a5e99e4..87f38a714b 100644
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -154,7 +154,7 @@ class MockAudioRendererHost : public AudioRendererHost {
class AudioRendererHostTest : public testing::Test {
public:
AudioRendererHostTest() {
- audio_manager_.reset(media::AudioManager::Create());
+ audio_manager_.reset(media::AudioManager::CreateForTesting());
media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
media_stream_manager_->UseFakeDevice();
host_ = new MockAudioRendererHost(audio_manager_.get(),
diff --git a/content/browser/renderer_host/media/desktop_capture_device_ash.cc b/content/browser/renderer_host/media/desktop_capture_device_aura.cc
index 08a74826b4..5419488c88 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_ash.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device_aura.cc
@@ -1,8 +1,8 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-//
-#include "content/browser/renderer_host/media/desktop_capture_device_ash.h"
+
+#include "content/browser/renderer_host/media/desktop_capture_device_aura.h"
#include "base/logging.h"
#include "base/timer/timer.h"
@@ -41,6 +41,9 @@ class DesktopVideoCaptureMachine
virtual void Stop() OVERRIDE;
// Implements aura::WindowObserver.
+ virtual void OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) OVERRIDE;
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
// Implements ui::CompositorObserver.
@@ -60,6 +63,9 @@ class DesktopVideoCaptureMachine
// |dirty| is false for timer polls and true for compositor updates.
void Capture(bool dirty);
+ // Update capture size. Must be called on the UI thread.
+ void UpdateCaptureSize();
+
// Response callback for cc::Layer::RequestCopyOfOutput().
void DidCopyOutput(
scoped_refptr<media::VideoFrame> video_frame,
@@ -117,6 +123,9 @@ bool DesktopVideoCaptureMachine::Start(
DCHECK(oracle_proxy.get());
oracle_proxy_ = oracle_proxy;
+ // Update capture size.
+ UpdateCaptureSize();
+
// Start observing window events.
desktop_window_->AddObserver(this);
@@ -156,6 +165,14 @@ void DesktopVideoCaptureMachine::Stop() {
started_ = false;
}
+void DesktopVideoCaptureMachine::UpdateCaptureSize() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (oracle_proxy_ && desktop_layer_) {
+ oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel(
+ desktop_layer_, desktop_layer_->bounds().size()));
+ }
+}
+
void DesktopVideoCaptureMachine::Capture(bool dirty) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -248,6 +265,17 @@ void DesktopVideoCaptureMachine::DidCopyOutput(
base::Passed(&release_callback)));
}
+void DesktopVideoCaptureMachine::OnWindowBoundsChanged(
+ aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ DCHECK(desktop_window_ && window == desktop_window_);
+
+ // Post task to update capture size on UI thread.
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
+ &DesktopVideoCaptureMachine::UpdateCaptureSize, AsWeakPtr()));
+}
+
void DesktopVideoCaptureMachine::OnWindowDestroyed(aura::Window* window) {
DCHECK(desktop_window_ && window == desktop_window_);
desktop_window_ = NULL;
@@ -266,33 +294,33 @@ void DesktopVideoCaptureMachine::OnCompositingEnded(
} // namespace
-DesktopCaptureDeviceAsh::DesktopCaptureDeviceAsh(
+DesktopCaptureDeviceAura::DesktopCaptureDeviceAura(
const DesktopMediaID& source)
: impl_(new VideoCaptureDeviceImpl(scoped_ptr<VideoCaptureMachine>(
new DesktopVideoCaptureMachine(source)))) {}
-DesktopCaptureDeviceAsh::~DesktopCaptureDeviceAsh() {
- DVLOG(2) << "DesktopCaptureDeviceAsh@" << this << " destroying.";
+DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() {
+ DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying.";
}
// static
-media::VideoCaptureDevice* DesktopCaptureDeviceAsh::Create(
+media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create(
const DesktopMediaID& source) {
// This implementation only supports screen capture.
if (source.type != DesktopMediaID::TYPE_SCREEN)
return NULL;
- return new DesktopCaptureDeviceAsh(source);
+ return new DesktopCaptureDeviceAura(source);
}
-void DesktopCaptureDeviceAsh::AllocateAndStart(
+void DesktopCaptureDeviceAura::AllocateAndStart(
const media::VideoCaptureParams& params,
scoped_ptr<Client> client) {
DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
impl_->AllocateAndStart(params, client.Pass());
}
-void DesktopCaptureDeviceAsh::StopAndDeAllocate() {
+void DesktopCaptureDeviceAura::StopAndDeAllocate() {
impl_->StopAndDeAllocate();
}
diff --git a/content/browser/renderer_host/media/desktop_capture_device_ash.h b/content/browser/renderer_host/media/desktop_capture_device_aura.h
index 95969a8e6b..bd0d7180b9 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_ash.h
+++ b/content/browser/renderer_host/media/desktop_capture_device_aura.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_ASH_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_ASH_H_
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_AURA_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_AURA_H_
#include <string>
@@ -20,14 +20,14 @@ namespace content {
class VideoCaptureDeviceImpl;
-// An implementation of VideoCaptureDevice that mirrors the desktop on Ash.
-class CONTENT_EXPORT DesktopCaptureDeviceAsh
+// An implementation of VideoCaptureDevice that mirrors an Aura window.
+class CONTENT_EXPORT DesktopCaptureDeviceAura
: public media::VideoCaptureDevice {
public:
- // Creates a VideoCaptureDevice for the Ash desktop.
+ // Creates a VideoCaptureDevice for the Aura desktop.
static media::VideoCaptureDevice* Create(const DesktopMediaID& source);
- virtual ~DesktopCaptureDeviceAsh();
+ virtual ~DesktopCaptureDeviceAura();
// VideoCaptureDevice implementation.
virtual void AllocateAndStart(const media::VideoCaptureParams& params,
@@ -35,14 +35,14 @@ class CONTENT_EXPORT DesktopCaptureDeviceAsh
virtual void StopAndDeAllocate() OVERRIDE;
private:
- DesktopCaptureDeviceAsh(const DesktopMediaID& source);
+ DesktopCaptureDeviceAura(const DesktopMediaID& source);
const scoped_ptr<class VideoCaptureDeviceImpl> impl_;
- DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAsh);
+ DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAura);
};
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_ASH_H_
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_DESKTOP_CAPTURE_DEVICE_AURA_H_
diff --git a/content/browser/renderer_host/media/desktop_capture_device_ash_unittest.cc b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc
index 2e82475219..1e87c69300 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_ash_unittest.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/media/desktop_capture_device_ash.h"
+#include "content/browser/renderer_host/media/desktop_capture_device_aura.h"
#include "base/synchronization/waitable_event.h"
#include "content/browser/browser_thread_impl.h"
@@ -49,18 +49,18 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
};
// Test harness that sets up a minimal environment with necessary stubs.
-class DesktopCaptureDeviceAshTest : public testing::Test {
+class DesktopCaptureDeviceAuraTest : public testing::Test {
public:
- DesktopCaptureDeviceAshTest()
+ DesktopCaptureDeviceAuraTest()
: browser_thread_for_ui_(BrowserThread::UI, &message_loop_) {}
- virtual ~DesktopCaptureDeviceAshTest() {}
+ virtual ~DesktopCaptureDeviceAuraTest() {}
protected:
virtual void SetUp() OVERRIDE {
helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
helper_->SetUp();
- // We need a window to cover desktop area so that DesktopCaptureDeviceAsh
+ // We need a window to cover desktop area so that DesktopCaptureDeviceAura
// can use gfx::NativeWindow::GetWindowAtScreenPoint() to locate the
// root window associated with the primary display.
gfx::Rect desktop_bounds = root_window()->bounds();
@@ -90,13 +90,13 @@ class DesktopCaptureDeviceAshTest : public testing::Test {
scoped_ptr<aura::Window> desktop_window_;
scoped_ptr<aura::test::TestWindowDelegate> window_delegate_;
- DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAshTest);
+ DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAuraTest);
};
-TEST_F(DesktopCaptureDeviceAshTest, StartAndStop) {
+TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
DesktopMediaID source(DesktopMediaID::TYPE_SCREEN, 0);
scoped_ptr<media::VideoCaptureDevice> capture_device(
- DesktopCaptureDeviceAsh::Create(source));
+ DesktopCaptureDeviceAura::Create(source));
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
EXPECT_CALL(*client, OnError()).Times(0);
diff --git a/content/browser/renderer_host/media/device_request_message_filter.cc b/content/browser/renderer_host/media/device_request_message_filter.cc
index 5eaf7c6bb3..a1801e7cc0 100644
--- a/content/browser/renderer_host/media/device_request_message_filter.cc
+++ b/content/browser/renderer_host/media/device_request_message_filter.cc
@@ -7,7 +7,6 @@
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/common/media/media_stream_messages.h"
-#include "content/public/browser/media_device_id.h"
#include "content/public/browser/resource_context.h"
// Clears the MediaStreamDevice.name from all devices in |device_list|.
@@ -97,12 +96,12 @@ void DeviceRequestMessageFilter::DevicesEnumerated(
if (label == request_it->audio_devices_label) {
request_it->has_audio_returned = true;
DCHECK(audio_devices->empty());
- HmacDeviceIds(request_it->origin, new_devices, audio_devices);
+ *audio_devices = new_devices;
} else {
DCHECK(label == request_it->video_devices_label);
request_it->has_video_returned = true;
DCHECK(video_devices->empty());
- HmacDeviceIds(request_it->origin, new_devices, video_devices);
+ *video_devices = new_devices;
}
if (!request_it->has_audio_returned || !request_it->has_video_returned) {
@@ -151,33 +150,18 @@ void DeviceRequestMessageFilter::OnChannelClosing() {
requests_.clear();
}
-void DeviceRequestMessageFilter::HmacDeviceIds(
- const GURL& origin,
- const StreamDeviceInfoArray& raw_devices,
- StreamDeviceInfoArray* devices_with_guids) {
- DCHECK(devices_with_guids);
-
- // Replace raw ids with hmac'd ids before returning to renderer process.
- for (StreamDeviceInfoArray::const_iterator device_itr = raw_devices.begin();
- device_itr != raw_devices.end();
- ++device_itr) {
- StreamDeviceInfo current_device_info = *device_itr;
- current_device_info.device.id =
- content::GetHMACForMediaDeviceID(origin, device_itr->device.id);
- devices_with_guids->push_back(current_device_info);
- }
-}
-
void DeviceRequestMessageFilter::OnGetSources(int request_id,
const GURL& security_origin) {
// Make request to get audio devices.
const std::string& audio_label = media_stream_manager_->EnumerateDevices(
- this, -1, -1, -1, MEDIA_DEVICE_AUDIO_CAPTURE, security_origin);
+ this, -1, -1, resource_context_, -1, MEDIA_DEVICE_AUDIO_CAPTURE,
+ security_origin);
DCHECK(!audio_label.empty());
// Make request for video devices.
const std::string& video_label = media_stream_manager_->EnumerateDevices(
- this, -1, -1, -1, MEDIA_DEVICE_VIDEO_CAPTURE, security_origin);
+ this, -1, -1, resource_context_, -1, MEDIA_DEVICE_VIDEO_CAPTURE,
+ security_origin);
DCHECK(!video_label.empty());
requests_.push_back(DeviceRequest(
diff --git a/content/browser/renderer_host/media/device_request_message_filter.h b/content/browser/renderer_host/media/device_request_message_filter.h
index edae564d10..4ea2c67a88 100644
--- a/content/browser/renderer_host/media/device_request_message_filter.h
+++ b/content/browser/renderer_host/media/device_request_message_filter.h
@@ -53,9 +53,6 @@ class CONTENT_EXPORT DeviceRequestMessageFilter : public BrowserMessageFilter,
private:
void OnGetSources(int request_id, const GURL& security_origin);
- void HmacDeviceIds(const GURL& origin,
- const StreamDeviceInfoArray& raw_devices,
- StreamDeviceInfoArray* devices_with_guids);
// Owned by ProfileIOData which is guaranteed to outlive DRMF.
ResourceContext* resource_context_;
diff --git a/content/browser/renderer_host/media/device_request_message_filter_unittest.cc b/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
index c3ffe9576f..16435dcf2a 100644
--- a/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
+++ b/content/browser/renderer_host/media/device_request_message_filter_unittest.cc
@@ -6,7 +6,6 @@
#include "content/browser/renderer_host/media/device_request_message_filter.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/common/media/media_stream_messages.h"
-#include "content/public/browser/media_device_id.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -26,10 +25,11 @@ class MockMediaStreamManager : public MediaStreamManager {
virtual ~MockMediaStreamManager() {}
- MOCK_METHOD6(EnumerateDevices,
+ MOCK_METHOD7(EnumerateDevices,
std::string(MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
MediaStreamType type,
const GURL& security_origin));
@@ -38,6 +38,7 @@ class MockMediaStreamManager : public MediaStreamManager {
std::string DoEnumerateDevices(MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
MediaStreamType type,
const GURL& security_origin) {
@@ -94,10 +95,10 @@ class DeviceRequestMessageFilterTest : public testing::Test {
AddVideoDevices(number_video_devices);
GURL origin("https://test.com");
EXPECT_CALL(*media_stream_manager_,
- EnumerateDevices(_, _, _, _, MEDIA_DEVICE_AUDIO_CAPTURE, _))
+ EnumerateDevices(_, _, _, _, _, MEDIA_DEVICE_AUDIO_CAPTURE, _))
.Times(1);
EXPECT_CALL(*media_stream_manager_,
- EnumerateDevices(_, _, _, _, MEDIA_DEVICE_VIDEO_CAPTURE, _))
+ EnumerateDevices(_, _, _, _, _, MEDIA_DEVICE_VIDEO_CAPTURE, _))
.Times(1);
// Send message to get devices. Should trigger 2 EnumerateDevice() requests.
const int kRequestId = 123;
@@ -118,11 +119,6 @@ class DeviceRequestMessageFilterTest : public testing::Test {
host_->requested_devices().size());
EXPECT_EQ(kRequestId, host_->received_id());
- // Check to make sure no devices have raw ids.
- EXPECT_FALSE(DoesContainRawIds(host_->requested_devices()));
-
- // Check to make sure every GUID produced matches a raw device id.
- EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->requested_devices(), origin));
}
bool AreLabelsPresent(MediaStreamType type) {
@@ -143,7 +139,7 @@ class DeviceRequestMessageFilterTest : public testing::Test {
new TestBrowserThread(BrowserThread::IO, message_loop_.get()));
media_stream_manager_.reset(new MockMediaStreamManager());
- ON_CALL(*media_stream_manager_, EnumerateDevices(_, _, _, _, _, _))
+ ON_CALL(*media_stream_manager_, EnumerateDevices(_, _, _, _, _, _, _))
.WillByDefault(Invoke(media_stream_manager_.get(),
&MockMediaStreamManager::DoEnumerateDevices));
@@ -199,48 +195,6 @@ class DeviceRequestMessageFilterTest : public testing::Test {
host_->DevicesEnumerated(kVideoLabel, physical_video_devices_);
}
- bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
- for (size_t i = 0; i < devices.size(); i++) {
- for (size_t j = 0; j < physical_audio_devices_.size(); ++j) {
- if (physical_audio_devices_[j].device.id == devices[i].device.id)
- return true;
- }
- for (size_t j = 0; j < physical_video_devices_.size(); ++j) {
- if (physical_video_devices_[j].device.id == devices[i].device.id)
- return true;
- }
- }
- return false;
- }
-
- bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
- const GURL& origin) {
- for (size_t i = 0; i < devices.size(); i++) {
- bool found_match = false;
- for (size_t j = 0; j < physical_audio_devices_.size(); ++j) {
- if (content::DoesMediaDeviceIDMatchHMAC(
- origin,
- devices[i].device.id,
- physical_audio_devices_[j].device.id)) {
- EXPECT_FALSE(found_match);
- found_match = true;
- }
- }
- for (size_t j = 0; j < physical_video_devices_.size(); ++j) {
- if (content::DoesMediaDeviceIDMatchHMAC(
- origin,
- devices[i].device.id,
- physical_video_devices_[j].device.id)) {
- EXPECT_FALSE(found_match);
- found_match = true;
- }
- }
- if (!found_match)
- return false;
- }
- return true;
- }
-
int next_device_id_;
};
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index ef91e0f36f..5ce805e643 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -14,8 +14,10 @@ namespace content {
MediaStreamDispatcherHost::MediaStreamDispatcherHost(
int render_process_id,
+ ResourceContext* resource_context,
MediaStreamManager* media_stream_manager)
: render_process_id_(render_process_id),
+ resource_context_(resource_context),
media_stream_manager_(media_stream_manager) {
}
@@ -70,7 +72,7 @@ void MediaStreamDispatcherHost::DevicesEnumerated(
StreamRequest request = it->second;
Send(new MediaStreamMsg_DevicesEnumerated(
- request.render_view_id, request.page_request_id, label, devices));
+ request.render_view_id, request.page_request_id, devices));
}
void MediaStreamDispatcherHost::DeviceOpened(
@@ -80,16 +82,6 @@ void MediaStreamDispatcherHost::DeviceOpened(
DVLOG(1) << "MediaStreamDispatcherHost::DeviceOpened("
<< ", {label = " << label << "})";
- // TODO(perkj): Checking for StreamRequest here is a temporary fix to avoid
- // an Assert in PopRequest. Remove this once the real problem is solved.
- // crbug/316396.
- StreamMap::iterator it = streams_.find(label);
- DCHECK(it != streams_.end());
- if (it == streams_.end()) {
- LOG(ERROR) << "DeviceOpened but there is no request for the device.";
- return;
- }
-
StreamRequest request = PopRequest(label);
Send(new MediaStreamMsg_DeviceOpened(
@@ -145,14 +137,11 @@ void MediaStreamDispatcherHost::OnGenerateStream(
<< security_origin.spec() << ")";
const std::string& label = media_stream_manager_->GenerateStream(
- this, render_process_id_, render_view_id, page_request_id,
+ this, render_process_id_, render_view_id, resource_context_,
+ page_request_id,
components, security_origin);
- if (label.empty()) {
- Send(new MediaStreamMsg_StreamGenerationFailed(render_view_id,
- page_request_id));
- } else {
- StoreRequest(render_view_id, page_request_id, label);
- }
+ CHECK(!label.empty());
+ StoreRequest(render_view_id, page_request_id, label);
}
void MediaStreamDispatcherHost::OnCancelGenerateStream(int render_view_id,
@@ -194,25 +183,20 @@ void MediaStreamDispatcherHost::OnEnumerateDevices(
<< security_origin.spec() << ")";
const std::string& label = media_stream_manager_->EnumerateDevices(
- this, render_process_id_, render_view_id, page_request_id,
- type, security_origin);
+ this, render_process_id_, render_view_id, resource_context_,
+ page_request_id, type, security_origin);
StoreRequest(render_view_id, page_request_id, label);
}
void MediaStreamDispatcherHost::OnCancelEnumerateDevices(
int render_view_id,
- const std::string& label) {
+ int page_request_id) {
DVLOG(1) << "MediaStreamDispatcherHost::OnCancelEnumerateDevices("
<< render_view_id << ", "
- << label << ")";
+ << page_request_id << ")";
- if (streams_.find(label) == streams_.end()) {
- // According to the comments in MediaStreamDispatcher::OnDevicesEnumerated,
- // OnCancelEnumerateDevices can be called several times with the same label.
- DVLOG(1) << "Enumeration request with label " << label
- << "does not exist.";
- return;
- }
+ std::string label;
+ GetRequestLabel(render_view_id, page_request_id, &label);
media_stream_manager_->CancelRequest(label);
PopRequest(label);
}
@@ -231,8 +215,8 @@ void MediaStreamDispatcherHost::OnOpenDevice(
<< security_origin.spec() << ")";
const std::string& label = media_stream_manager_->OpenDevice(
- this, render_process_id_, render_view_id, page_request_id,
- device_id, type, security_origin);
+ this, render_process_id_, render_view_id, resource_context_,
+ page_request_id, device_id, type, security_origin);
StoreRequest(render_view_id, page_request_id, label);
}
@@ -264,4 +248,17 @@ MediaStreamDispatcherHost::PopRequest(const std::string& label) {
return request;
}
+void MediaStreamDispatcherHost::GetRequestLabel(
+ int render_view_id, int page_request_id, std::string* label) {
+ for (StreamMap::const_iterator it = streams_.begin(); it != streams_.end();
+ ++it) {
+ if (it->second.render_view_id == render_view_id &&
+ it->second.page_request_id == page_request_id) {
+ *label = it->first;
+ return;
+ }
+ }
+ NOTREACHED();
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index 7649bb61b8..1dd72dc577 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -14,8 +14,10 @@
#include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/resource_context.h"
namespace content {
+
class MediaStreamManager;
// MediaStreamDispatcherHost is a delegate for Media Stream API messages used by
@@ -25,6 +27,7 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
public MediaStreamRequester {
public:
MediaStreamDispatcherHost(int render_process_id,
+ ResourceContext* resource_context,
MediaStreamManager* media_stream_manager);
// MediaStreamRequester implementation.
@@ -79,7 +82,7 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
const GURL& security_origin);
void OnCancelEnumerateDevices(int render_view_id,
- const std::string& label);
+ int page_request_id);
void OnOpenDevice(int render_view_id,
int page_request_id,
@@ -94,8 +97,12 @@ class CONTENT_EXPORT MediaStreamDispatcherHost : public BrowserMessageFilter,
int page_request_id,
const std::string& label);
StreamRequest PopRequest(const std::string& label);
+ void GetRequestLabel(int render_view_id,
+ int page_request_id,
+ std::string* label);
int render_process_id_;
+ ResourceContext* resource_context_;
MediaStreamManager* media_stream_manager_;
// Active requests. When the MediaStreamManager responds to a a request the
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index e17302ff04..0b0ef5c907 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -15,12 +15,14 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/common/media/media_stream_messages.h"
#include "content/common/media/media_stream_options.h"
+#include "content/public/browser/media_device_id.h"
#include "content/public/test/mock_resource_context.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
#include "ipc/ipc_message_macros.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/mock_audio_manager.h"
#include "media/video/capture/fake_video_capture_device.h"
#include "net/url_request/url_request_context.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -42,9 +44,10 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
public TestContentBrowserClient {
public:
MockMediaStreamDispatcherHost(
+ ResourceContext* resource_context,
const scoped_refptr<base::MessageLoopProxy>& message_loop,
MediaStreamManager* manager)
- : MediaStreamDispatcherHost(kProcessId, manager),
+ : MediaStreamDispatcherHost(kProcessId, resource_context, manager),
message_loop_(message_loop) {}
// A list of mock methods.
@@ -59,10 +62,11 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
void OnGenerateStream(int render_view_id,
int page_request_id,
const StreamOptions& components,
+ const GURL& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnGenerateStream(
- render_view_id, page_request_id, components, GURL());
+ render_view_id, page_request_id, components, security_origin);
}
void OnStopStreamDevice(int render_view_id,
@@ -74,25 +78,28 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
+ const GURL& security_origin,
const base::Closure& quit_closure) {
quit_closures_.push(quit_closure);
MediaStreamDispatcherHost::OnOpenDevice(
- render_view_id, page_request_id, device_id, type, GURL());
+ render_view_id, page_request_id, device_id, type, security_origin);
}
- bool FindExistingRequestedDeviceInfo(const std::string& device_id,
- MediaStreamRequestType request_type,
- StreamDeviceInfo* device_info) {
- MediaRequestState request_state;
- return media_stream_manager_->FindExistingRequestedDeviceInfo(
- kProcessId, kRenderId, request_type, device_id, device_info,
- &request_state);
+ void OnEnumerateDevices(int render_view_id,
+ int page_request_id,
+ MediaStreamType type,
+ const GURL& security_origin,
+ const base::Closure& quit_closure) {
+ quit_closures_.push(quit_closure);
+ MediaStreamDispatcherHost::OnEnumerateDevices(
+ render_view_id, page_request_id, type, security_origin);
}
std::string label_;
StreamDeviceInfoArray audio_devices_;
StreamDeviceInfoArray video_devices_;
StreamDeviceInfo opened_device_;
+ StreamDeviceInfoArray enumerated_devices_;
private:
virtual ~MockMediaStreamDispatcherHost() {}
@@ -112,6 +119,8 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
OnStreamGenerationFailed)
IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStopped)
IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpened)
+ IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated,
+ OnDevicesEnumerated)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
EXPECT_TRUE(handled);
@@ -153,14 +162,12 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
void OnDeviceStopped(const IPC::Message& msg,
const std::string& label,
const content::StreamDeviceInfo& device) {
+ if (IsVideoMediaType(device.device.type))
+ EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
+ if (IsAudioMediaType(device.device.type))
+ EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
+
OnDeviceStopped(msg.routing_id());
- // Notify that the event have occurred.
- if (!quit_closures_.empty()) {
- base::Closure quit_closure = quit_closures_.front();
- quit_closures_.pop();
- message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
- }
- label_ = "";
}
void OnDeviceOpened(const IPC::Message& msg,
@@ -174,6 +181,15 @@ class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
opened_device_ = device;
}
+ void OnDevicesEnumerated(const IPC::Message& msg,
+ int request_id,
+ const StreamDeviceInfoArray& devices) {
+ base::Closure quit_closure = quit_closures_.front();
+ quit_closures_.pop();
+ message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
+ enumerated_devices_ = devices;
+ }
+
scoped_refptr<base::MessageLoopProxy> message_loop_;
std::queue<base::Closure> quit_closures_;
@@ -188,15 +204,19 @@ class MediaStreamDispatcherHostTest : public testing::Test {
public:
MediaStreamDispatcherHostTest()
: old_browser_client_(NULL),
- thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
+ thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+ origin_("https://test.com") {
+ audio_manager_.reset(
+ new media::MockAudioManager(base::MessageLoopProxy::current()));
// Create our own MediaStreamManager.
- audio_manager_.reset(media::AudioManager::Create());
media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
// Make sure we use fake devices to avoid long delays.
media_stream_manager_->UseFakeDevice();
- host_ = new MockMediaStreamDispatcherHost(base::MessageLoopProxy::current(),
- media_stream_manager_.get());
+ host_ = new MockMediaStreamDispatcherHost(
+ browser_context_.GetResourceContext(),
+ base::MessageLoopProxy::current(),
+ media_stream_manager_.get());
// Use the fake content client and browser.
content_client_.reset(new TestContentClient());
@@ -205,10 +225,14 @@ class MediaStreamDispatcherHostTest : public testing::Test {
}
virtual ~MediaStreamDispatcherHostTest() {
- // Recover the old browser client and content client.
- SetBrowserClientForTesting(old_browser_client_);
- content_client_.reset();
- media_stream_manager_->WillDestroyCurrentMessageLoop();
+ }
+
+ virtual void SetUp() OVERRIDE {
+ media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
+ ASSERT_GT(physical_video_devices_.size(), 0u);
+
+ audio_manager_->GetAudioInputDeviceNames(&physical_audio_devices_);
+ ASSERT_GT(physical_audio_devices_.size(), 0u);
}
virtual void TearDown() OVERRIDE {
@@ -229,9 +253,33 @@ class MediaStreamDispatcherHostTest : public testing::Test {
int page_request_id,
const StreamOptions& options) {
base::RunLoop run_loop;
- host_->OnGenerateStream(render_view_id, page_request_id, options,
+ int expected_audio_array_size =
+ (options.audio_type != MEDIA_NO_SERVICE &&
+ physical_audio_devices_.size() > 0) ? 1 : 0;
+ int expected_video_array_size =
+ (options.video_type != MEDIA_NO_SERVICE &&
+ physical_video_devices_.size() > 0) ? 1 : 0;
+ EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
+ expected_audio_array_size,
+ expected_video_array_size));
+ host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
run_loop.QuitClosure());
run_loop.Run();
+ EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
+ EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
+ EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
+ EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
+ }
+
+ void GenerateStreamAndWaitForFailure(int render_view_id,
+ int page_request_id,
+ const StreamOptions& options) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(*host_.get(),
+ OnStreamGenerationFailed(render_view_id, page_request_id));
+ host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
+ run_loop.QuitClosure());
+ run_loop.Run();
}
void OpenVideoDeviceAndWaitForResult(int render_view_id,
@@ -239,9 +287,75 @@ class MediaStreamDispatcherHostTest : public testing::Test {
const std::string& device_id) {
base::RunLoop run_loop;
host_->OnOpenDevice(render_view_id, page_request_id, device_id,
- MEDIA_DEVICE_VIDEO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
run_loop.QuitClosure());
run_loop.Run();
+ EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
+ EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
+ }
+
+ void EnumerateDevicesAndWaitForResult(int render_view_id,
+ int page_request_id,
+ MediaStreamType type) {
+ base::RunLoop run_loop;
+ host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ ASSERT_FALSE(host_->enumerated_devices_.empty());
+ EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
+ EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
+ }
+
+ bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
+ for (size_t i = 0; i < devices.size(); ++i) {
+ media::AudioDeviceNames::const_iterator audio_it =
+ physical_audio_devices_.begin();
+ for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
+ if (audio_it->unique_id == devices[i].device.id)
+ return true;
+ }
+ media::VideoCaptureDevice::Names::const_iterator video_it =
+ physical_video_devices_.begin();
+ for (; video_it != physical_video_devices_.end(); ++video_it) {
+ if (video_it->id() == devices[i].device.id)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
+ const GURL& origin) {
+ for (size_t i = 0; i < devices.size(); ++i) {
+ bool found_match = false;
+ media::AudioDeviceNames::const_iterator audio_it =
+ physical_audio_devices_.begin();
+ for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
+ if (content::DoesMediaDeviceIDMatchHMAC(
+ browser_context_.GetResourceContext(),
+ origin,
+ devices[i].device.id,
+ audio_it->unique_id)) {
+ EXPECT_FALSE(found_match);
+ found_match = true;
+ }
+ }
+ media::VideoCaptureDevice::Names::const_iterator video_it =
+ physical_video_devices_.begin();
+ for (; video_it != physical_video_devices_.end(); ++video_it) {
+ if (content::DoesMediaDeviceIDMatchHMAC(
+ browser_context_.GetResourceContext(),
+ origin,
+ devices[i].device.id,
+ video_it->id())) {
+ EXPECT_FALSE(found_match);
+ found_match = true;
+ }
+ }
+ if (!found_match)
+ return false;
+ }
+ return true;
}
scoped_refptr<MockMediaStreamDispatcherHost> host_;
@@ -250,19 +364,32 @@ class MediaStreamDispatcherHostTest : public testing::Test {
ContentBrowserClient* old_browser_client_;
scoped_ptr<ContentClient> content_client_;
content::TestBrowserThreadBundle thread_bundle_;
+ content::TestBrowserContext browser_context_;
+ media::AudioDeviceNames physical_audio_devices_;
+ media::VideoCaptureDevice::Names physical_video_devices_;
+ GURL origin_;
};
TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
}
+TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_NO_SERVICE);
+
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+
+ EXPECT_EQ(host_->audio_devices_.size(), 1u);
+ EXPECT_EQ(host_->video_devices_.size(), 0u);
+}
+
// This test generates two streams with video only using the same render view
// id. The same capture device with the same device and session id is expected
// to be used.
@@ -271,7 +398,6 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
// Generate first stream.
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
// Check the latest generated stream.
@@ -283,8 +409,6 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
// Generate second stream.
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(),
- OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
// Check the latest generated stream.
@@ -304,7 +428,6 @@ TEST_F(MediaStreamDispatcherHostTest,
// Generate first stream.
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
@@ -333,7 +456,6 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
// Generate first stream.
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
// Check the latest generated stream.
@@ -345,8 +467,6 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
// Generate second stream from another render view.
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(),
- OnStreamGenerated(kRenderId+1, kPageRequestId + 1, 0, 1));
GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
// Check the latest generated stream.
@@ -376,41 +496,153 @@ TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
base::RunLoop run_loop1;
base::RunLoop run_loop2;
- host_->OnGenerateStream(kRenderId, kPageRequestId, options,
+ host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
run_loop1.QuitClosure());
- host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
run_loop2.QuitClosure());
run_loop1.Run();
run_loop2.Run();
}
+// Test that we can generate streams where a sourceId is specified in the
+// request.
+TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithSourceId) {
+ ASSERT_GE(physical_audio_devices_.size(), 1u);
+ ASSERT_GE(physical_video_devices_.size(), 1u);
+
+ media::AudioDeviceNames::const_iterator audio_it =
+ physical_audio_devices_.begin();
+ for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+ options.audio_device_id = content::GetHMACForMediaDeviceID(
+ browser_context_.GetResourceContext(),
+ origin_,
+ audio_it->unique_id);
+ ASSERT_FALSE(options.audio_device_id.empty());
+
+ // Generate first stream.
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_EQ(host_->audio_devices_[0].device.id, options.audio_device_id);
+ }
+
+ media::VideoCaptureDevice::Names::const_iterator video_it =
+ physical_video_devices_.begin();
+ for (; video_it != physical_video_devices_.end(); ++video_it) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+ options.video_device_id = content::GetHMACForMediaDeviceID(
+ browser_context_.GetResourceContext(),
+ origin_,
+ video_it->id());
+ ASSERT_FALSE(options.video_device_id.empty());
+
+ // Generate first stream.
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_EQ(host_->video_devices_[0].device.id, options.video_device_id);
+ }
+}
+
+// Test that generating a stream with an invalid video source id fail.
+TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithInvalidVideoSourceId) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+ options.video_device_id = "invalid source id";
+
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_NE(host_->video_devices_[0].device.id, options.video_device_id);
+}
+
+// Test that generating a stream with an invalid audio source id fail.
+TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithInvalidAudioSourceId) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+ options.audio_device_id = "invalid source id";
+
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_NE(host_->audio_devices_[0].device.id, options.audio_device_id);
+}
+
+TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
+ size_t number_of_fake_devices = physical_video_devices_.size();
+ media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
+ media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_VIDEO_CAPTURE);
+
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_TRUE(host_->video_devices_.empty());
+
+ // Reset the number of fake devices for next test.
+ media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
+}
+
+// Test that if a OnStopStreamDevice message is received for a device that has
+// been opened in a MediaStream and by pepper, the device is only stopped for
+// the MediaStream.
TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
StreamOptions options(MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE);
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
- const std::string device_id = host_->video_devices_.front().device.id;
- const int session_id = host_->video_devices_.front().session_id;
- StreamDeviceInfo video_device_info;
- EXPECT_TRUE(host_->FindExistingRequestedDeviceInfo(device_id,
- MEDIA_GENERATE_STREAM,
- &video_device_info));
- EXPECT_EQ(video_device_info.device.id, device_id);
- EXPECT_EQ(video_device_info.session_id, session_id);
-
- OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id);
-
- host_->OnStopStreamDevice(kRenderId, device_id);
-
- EXPECT_FALSE(host_->FindExistingRequestedDeviceInfo(device_id,
- MEDIA_GENERATE_STREAM,
- &video_device_info));
- EXPECT_TRUE(host_->FindExistingRequestedDeviceInfo(device_id,
- MEDIA_OPEN_DEVICE,
- &video_device_info));
+ std::string stream_request_label = host_->label_;
+ StreamDeviceInfo video_device_info = host_->video_devices_.front();
+ ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
+ stream_request_label).size());
+
+ // Open the same device by Pepper.
+ OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
+ video_device_info.device.id);
+ std::string open_device_request_label = host_->label_;
+
+ // Stop the device in the MediaStream.
+ host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
+
+ EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
+ stream_request_label).size());
+ EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
+ open_device_request_label).size());
+}
+
+TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+
+ std::string request_label1 = host_->label_;
+ StreamDeviceInfo video_device_info = host_->video_devices_.front();
+ // Expect that 1 audio and 1 video device has been opened.
+ EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
+ request_label1).size());
+
+ host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
+ EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
+ request_label1).size());
+
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ std::string request_label2 = host_->label_;
+
+ StreamDeviceInfoArray request1_devices =
+ media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
+ StreamDeviceInfoArray request2_devices =
+ media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
+
+ ASSERT_EQ(1u, request1_devices.size());
+ ASSERT_EQ(2u, request2_devices.size());
+
+ // Test that the same audio device has been opened in both streams.
+ EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
+ request2_devices[0]) ||
+ StreamDeviceInfo::IsEqual(request1_devices[0],
+ request2_devices[1]));
}
TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
@@ -421,7 +653,7 @@ TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
// Create multiple GenerateStream requests.
size_t streams = 5;
for (size_t i = 1; i <= streams; ++i) {
- host_->OnGenerateStream(kRenderId, kPageRequestId + i, options,
+ host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
run_loop.QuitClosure());
}
@@ -437,8 +669,6 @@ TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
size_t generated_streams = 3;
for (size_t i = 0; i < generated_streams; ++i) {
SetupFakeUI(true);
- EXPECT_CALL(*host_.get(),
- OnStreamGenerated(kRenderId, kPageRequestId + i, 0, 1));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
}
@@ -456,16 +686,48 @@ TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
.WillOnce(SaveArg<0>(&close_callback));
media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
- EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
- EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
EXPECT_EQ(host_->audio_devices_.size(), 0u);
EXPECT_EQ(host_->video_devices_.size(), 1u);
ASSERT_FALSE(close_callback.is_null());
+ EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
close_callback.Run();
base::RunLoop().RunUntilIdle();
}
+// Test that the dispatcher is notified if a video device that is in use is
+// being unplugged.
+TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
+ size_t number_of_fake_devices = physical_video_devices_.size();
+ StreamOptions options(MEDIA_DEVICE_AUDIO_CAPTURE, MEDIA_DEVICE_VIDEO_CAPTURE);
+ SetupFakeUI(true);
+ GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
+ EXPECT_EQ(host_->audio_devices_.size(), 1u);
+ EXPECT_EQ(host_->video_devices_.size(), 1u);
+
+ media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
+ .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ media_stream_manager_->OnDevicesChanged(
+ base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
+
+ run_loop.Run();
+
+ media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
+}
+
+TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
+ EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
+ MEDIA_DEVICE_AUDIO_CAPTURE);
+}
+
+TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
+ EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
+ MEDIA_DEVICE_VIDEO_CAPTURE);
+}
+
}; // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index ab09254b31..2c36f314c7 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/rand_util.h"
+#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/device_request_message_filter.h"
@@ -63,17 +64,18 @@ static bool Requested(const MediaStreamRequest& request,
request.video_type == stream_type);
}
-// TODO(xians): Merge DeviceRequest with MediaStreamRequest.
class MediaStreamManager::DeviceRequest {
public:
DeviceRequest(MediaStreamRequester* requester,
const MediaStreamRequest& request,
int requesting_process_id,
- int requesting_view_id)
+ int requesting_view_id,
+ ResourceContext* resource_context)
: requester(requester),
request(request),
requesting_process_id(requesting_process_id),
requesting_view_id(requesting_view_id),
+ resource_context(resource_context),
state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) {
}
@@ -90,15 +92,9 @@ class MediaStreamManager::DeviceRequest {
state_[stream_type] = new_state;
}
- if (request.video_type != MEDIA_TAB_VIDEO_CAPTURE &&
- request.audio_type != MEDIA_TAB_AUDIO_CAPTURE &&
- new_state != MEDIA_REQUEST_STATE_CLOSING) {
- return;
- }
-
MediaObserver* media_observer =
GetContentClient()->browser()->GetMediaObserver();
- if (media_observer == NULL)
+ if (!media_observer)
return;
// If we appended a device_id scheme, we want to remove it when notifying
@@ -133,6 +129,8 @@ class MediaStreamManager::DeviceRequest {
// specifies the target renderer from which audio and video is captured.
const int requesting_view_id;
+ ResourceContext* resource_context;
+
StreamDeviceInfoArray devices;
// Callback to the requester which audio/video devices have been selected.
@@ -181,6 +179,7 @@ MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager)
}
MediaStreamManager::~MediaStreamManager() {
+ DVLOG(1) << "~MediaStreamManager";
DCHECK(requests_.empty());
DCHECK(!device_thread_.get());
}
@@ -207,28 +206,38 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Create a new request based on options.
MediaStreamRequest stream_request(
- render_process_id, render_view_id, page_request_id, std::string(),
+ render_process_id, render_view_id, page_request_id,
security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(),
options.audio_type, options.video_type);
+ // TODO(perkj): The argument list with NULL parameters to DeviceRequest
+ // suggests that this is the wrong design. Can this be refactored?
DeviceRequest* request = new DeviceRequest(NULL, stream_request,
- render_process_id, render_view_id);
+ render_process_id, render_view_id,
+ NULL);
const std::string& label = AddRequest(request);
request->callback = callback;
-
- HandleRequest(label);
-
+ // Post a task and handle the request asynchronously. The reason is that the
+ // requester won't have a label for the request until this function returns
+ // and thus can not handle a response. Using base::Unretained is safe since
+ // MediaStreamManager is deleted on the UI thread, after the IO thread has
+ // been stopped.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::SetupRequest,
+ base::Unretained(this), label));
return label;
}
-std::string MediaStreamManager::GenerateStream(
- MediaStreamRequester* requester,
- int render_process_id,
- int render_view_id,
- int page_request_id,
- const StreamOptions& options,
- const GURL& security_origin) {
+std::string MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
+ int render_process_id,
+ int render_view_id,
+ ResourceContext* rc,
+ int page_request_id,
+ const StreamOptions& options,
+ const GURL& security_origin) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DVLOG(1) << "GenerateStream()";
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream)) {
UseFakeDevice();
@@ -238,101 +247,51 @@ std::string MediaStreamManager::GenerateStream(
UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>());
}
- int target_render_process_id = render_process_id;
- int target_render_view_id = render_view_id;
- std::string tab_capture_device_id;
-
- // Customize options for a WebContents based capture.
- if (options.audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
- options.video_type == MEDIA_TAB_VIDEO_CAPTURE) {
- // TODO(justinlin): Can't plumb audio mirroring using stream type right
- // now, so plumbing by device_id. Will revisit once it's refactored.
- // http://crbug.com/163100
- tab_capture_device_id =
- WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
- !options.video_device_id.empty() ?
- options.video_device_id : options.audio_device_id);
-
- bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
- tab_capture_device_id, &target_render_process_id,
- &target_render_view_id);
- if (!has_valid_device_id ||
- (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE &&
- options.audio_type != MEDIA_NO_SERVICE) ||
- (options.video_type != MEDIA_TAB_VIDEO_CAPTURE &&
- options.video_type != MEDIA_NO_SERVICE)) {
- LOG(ERROR) << "Invalid request.";
- return std::string();
- }
- }
-
- std::string translated_audio_device_id;
- std::string translated_video_device_id;
- if (options.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
- bool found_match = TranslateGUIDToRawId(
- MEDIA_DEVICE_AUDIO_CAPTURE, security_origin, options.audio_device_id,
- &translated_audio_device_id);
- DCHECK(found_match || translated_audio_device_id.empty());
- }
-
- if (options.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
- bool found_match = TranslateGUIDToRawId(
- MEDIA_DEVICE_VIDEO_CAPTURE, security_origin, options.video_device_id,
- &translated_video_device_id);
- DCHECK(found_match || translated_video_device_id.empty());
- }
-
- if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE ||
- options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) {
- // For screen capture we only support two valid combinations:
- // (1) screen video capture only, or
- // (2) screen video capture with loopback audio capture.
- if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE ||
- (options.audio_type != MEDIA_NO_SERVICE &&
- options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) {
- // TODO(sergeyu): Surface error message to the calling JS code.
- LOG(ERROR) << "Invalid screen capture request.";
- return std::string();
- }
- translated_video_device_id = options.video_device_id;
- }
-
// Create a new request based on options.
MediaStreamRequest stream_request(
- target_render_process_id, target_render_view_id, page_request_id,
- tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM,
- translated_audio_device_id, translated_video_device_id,
+ render_process_id, render_view_id, page_request_id,
+ security_origin, MEDIA_GENERATE_STREAM,
+ options.audio_device_id, options.video_device_id,
options.audio_type, options.video_type);
DeviceRequest* request = new DeviceRequest(requester, stream_request,
render_process_id,
- render_view_id);
+ render_view_id,
+ rc);
const std::string& label = AddRequest(request);
- HandleRequest(label);
+
+ // Post a task and handle the request asynchronously. The reason is that the
+ // requester won't have a label for the request until this function returns
+ // and thus can not handle a response. Using base::Unretained is safe since
+ // MediaStreamManager is deleted on the UI thread, after the IO thread has
+ // been stopped.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::SetupRequest,
+ base::Unretained(this), label));
return label;
}
void MediaStreamManager::CancelRequest(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "CancelRequest({label = " << label << "})";
- DeviceRequests::iterator request_it = requests_.find(label);
- if (request_it == requests_.end()) {
- NOTREACHED();
+ DeviceRequest* request = FindRequest(label);
+ if (!request) {
+ // The request does not exist.
+ LOG(ERROR) << "The request with label = " << label << " does not exist.";
return;
}
- scoped_ptr<DeviceRequest> request(request_it->second);
- RemoveRequest(request_it);
-
if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) {
+ DeleteRequest(label);
return;
}
// This is a request for opening one or more devices.
for (StreamDeviceInfoArray::iterator device_it = request->devices.begin();
- device_it != request->devices.end(); ++device_it) {
+ device_it != request->devices.end(); ++device_it) {
+ MediaRequestState state = request->state(device_it->device.type);
// If we have not yet requested the device to be opened - just ignore it.
- if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING
- &&
- request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) {
+ if (state != MEDIA_REQUEST_STATE_OPENING &&
+ state != MEDIA_REQUEST_STATE_DONE) {
continue;
}
// Stop the opening/opened devices of the requests.
@@ -341,6 +300,7 @@ void MediaStreamManager::CancelRequest(const std::string& label) {
// Cancel the request if still pending at UI side.
request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING);
+ DeleteRequest(label);
}
void MediaStreamManager::CancelAllRequests(int render_process_id) {
@@ -363,7 +323,6 @@ void MediaStreamManager::StopStreamDevice(int render_process_id,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} "
<< ", {device_id = " << device_id << "})";
-
// Find the first request for this |render_process_id| and |render_view_id|
// of type MEDIA_GENERATE_STREAM that has requested to use |device_id| and
// stop it.
@@ -409,10 +368,9 @@ void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) {
}
// If this request doesn't have any active devices, remove the request.
if (devices->empty()) {
- DeviceRequests::iterator del_itor(request_it);
+ std::string label = request_it->first;
++request_it;
- scoped_ptr<DeviceRequest> request(del_itor->second);
- RemoveRequest(del_itor);
+ DeleteRequest(label);
} else {
++request_it;
}
@@ -444,67 +402,81 @@ std::string MediaStreamManager::EnumerateDevices(
MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
MediaStreamType type,
const GURL& security_origin) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(requester);
DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
type == MEDIA_DEVICE_VIDEO_CAPTURE);
- // When the requester is NULL, the request is made by the UI to ensure MSM
- // starts monitoring devices.
- if (!requester) {
- if (!monitoring_started_)
- StartMonitoring();
-
- return std::string();
- }
-
// Create a new request.
StreamOptions options;
- EnumerationCache* cache = NULL;
if (type == MEDIA_DEVICE_AUDIO_CAPTURE) {
options.audio_type = type;
- cache = &audio_enumeration_cache_;
} else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) {
options.video_type = type;
- cache = &video_enumeration_cache_;
} else {
NOTREACHED();
return std::string();
}
MediaStreamRequest stream_request(
- render_process_id, render_view_id, page_request_id, std::string(),
+ render_process_id, render_view_id, page_request_id,
security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(),
options.audio_type, options.video_type);
DeviceRequest* request = new DeviceRequest(requester, stream_request,
- render_process_id,
- render_view_id);
+ render_process_id, render_view_id,
+ rc);
const std::string& label = AddRequest(request);
+ // Post a task and handle the request asynchronously. The reason is that the
+ // requester won't have a label for the request until this function returns
+ // and thus can not handle a response. Using base::Unretained is safe since
+ // MediaStreamManager is deleted on the UI thread, after the IO thread has
+ // been stopped.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::DoEnumerateDevices,
+ base::Unretained(this), label));
+
+ return label;
+}
+
+void MediaStreamManager::DoEnumerateDevices(const std::string& label) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DeviceRequest* request = FindRequest(label);
+ if (!request)
+ return; // This can happen if the request has been canceled.
+
+ MediaStreamType type;
+ EnumerationCache* cache;
+ if (request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
+ DCHECK_EQ(MEDIA_NO_SERVICE, request->request.video_type);
+ type = MEDIA_DEVICE_AUDIO_CAPTURE;
+ cache = &audio_enumeration_cache_;
+ } else {
+ DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->request.video_type);
+ type = MEDIA_DEVICE_VIDEO_CAPTURE;
+ cache = &video_enumeration_cache_;
+ }
if (cache->valid) {
// Cached device list of this type exists. Just send it out.
request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED);
-
- // Need to post a task since the requester won't have label till
- // this function returns.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&MediaStreamManager::SendCachedDeviceList,
- base::Unretained(this), cache, label));
+ request->devices = cache->devices;
+ FinalizeEnumerateDevices(label, request);
} else {
StartEnumeration(request);
}
-
DVLOG(1) << "Enumerate Devices ({label = " << label << "})";
- return label;
}
std::string MediaStreamManager::OpenDevice(
MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
@@ -527,29 +499,31 @@ std::string MediaStreamManager::OpenDevice(
}
MediaStreamRequest stream_request(
- render_process_id, render_view_id, page_request_id, std::string(),
+ render_process_id, render_view_id, page_request_id,
security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id,
options.video_device_id, options.audio_type, options.video_type);
DeviceRequest* request = new DeviceRequest(requester, stream_request,
- render_process_id,
- render_view_id);
+ render_process_id, render_view_id,
+ rc);
const std::string& label = AddRequest(request);
- StartEnumeration(request);
+ // Post a task and handle the request asynchronously. The reason is that the
+ // requester won't have a label for the request until this function returns
+ // and thus can not handle a response. Using base::Unretained is safe since
+ // MediaStreamManager is deleted on the UI thread, after the IO thread has
+ // been stopped.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&MediaStreamManager::SetupRequest,
+ base::Unretained(this), label));
DVLOG(1) << "OpenDevice ({label = " << label << "})";
return label;
}
-void MediaStreamManager::SendCachedDeviceList(
- EnumerationCache* cache,
- const std::string& label) {
+void MediaStreamManager::EnsureDeviceMonitorStarted() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (cache->valid) {
- DeviceRequests::iterator it = requests_.find(label);
- if (it != requests_.end()) {
- it->second->requester->DevicesEnumerated(label, cache->devices);
- }
- }
+ if (!monitoring_started_)
+ StartMonitoring();
}
void MediaStreamManager::StopRemovedDevices(
@@ -585,7 +559,12 @@ void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) {
for (StreamDeviceInfoArray::const_iterator device_it =
request->devices.begin();
device_it != request->devices.end(); ++device_it) {
- if (device_it->device.IsEqual(device)) {
+ std::string source_id = content::GetHMACForMediaDeviceID(
+ request->resource_context,
+ request->request.security_origin,
+ device.id);
+ if (device_it->device.id == source_id &&
+ device_it->device.type == device.type) {
session_ids.push_back(device_it->session_id);
if (it->second->requester) {
it->second->requester->DeviceStopped(
@@ -630,14 +609,69 @@ void MediaStreamManager::StopMonitoring() {
}
}
-bool MediaStreamManager::TranslateGUIDToRawId(MediaStreamType stream_type,
- const GURL& security_origin,
- const std::string& device_guid,
- std::string* raw_device_id) {
+bool MediaStreamManager::TranslateRequestedSourceIdToDeviceId(
+ DeviceRequest* request) {
+ MediaStreamRequest* ms_request = &request->request;
+ // If a specific device has been requested we need to find the real device id.
+ if (ms_request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE &&
+ !ms_request->requested_audio_device_id.empty()) {
+ if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE,
+ request->resource_context,
+ ms_request->security_origin,
+ ms_request->requested_audio_device_id,
+ &ms_request->requested_audio_device_id)) {
+ // TODO(perkj): gUM should support mandatory and optional constraints.
+ // Ie - if the sourceId is mandatory but it does not match - gUM should
+ // fail. For now we treat sourceId as an optional constraint.
+ LOG(WARNING) << "Requested device does not exist.";
+ ms_request->requested_audio_device_id = "";
+ return true;;
+ }
+ }
+
+ if (ms_request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE &&
+ !ms_request->requested_video_device_id.empty()) {
+ if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE,
+ request->resource_context,
+ ms_request->security_origin,
+ ms_request->requested_video_device_id,
+ &ms_request->requested_video_device_id)) {
+ // TODO(perkj): gUM should support mandatory and optional constraints.
+ // Ie - if the sourceId is mandatory but it does not match - gUM should
+ // fail. For now we treat sourceId as an optional constraint.
+ LOG(WARNING) << "Requested device does not exist.";
+ ms_request->requested_video_device_id = "";
+ return true;
+ }
+ }
+ DVLOG(3) << "Requested audio device "
+ << ms_request->requested_audio_device_id
+ << "Requested video device "
+ << ms_request->requested_video_device_id;
+ return true;
+}
+
+void MediaStreamManager::TranslateDeviceIdToSourceId(
+ DeviceRequest* request,
+ MediaStreamDevice* device) {
+ if (request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ||
+ request->request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
+ device->id = content::GetHMACForMediaDeviceID(
+ request->resource_context,
+ request->request.security_origin,
+ device->id);
+ }
+}
+
+bool MediaStreamManager::TranslateSourceIdToDeviceId(
+ MediaStreamType stream_type,
+ ResourceContext* rc,
+ const GURL& security_origin,
+ const std::string& source_id,
+ std::string* device_id) {
DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ||
stream_type == MEDIA_DEVICE_VIDEO_CAPTURE);
- if (device_guid.empty())
- return false;
+ DCHECK(!source_id.empty());
EnumerationCache* cache =
stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ?
@@ -650,9 +684,9 @@ bool MediaStreamManager::TranslateGUIDToRawId(MediaStreamType stream_type,
for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin();
it != cache->devices.end();
++it) {
- if (content::DoesMediaDeviceIDMatchHMAC(
- security_origin, device_guid, it->device.id)) {
- *raw_device_id = it->device.id;
+ if (content::DoesMediaDeviceIDMatchHMAC(rc, security_origin, source_id,
+ it->device.id)) {
+ *device_id = it->device.id;
return true;
}
}
@@ -700,13 +734,36 @@ std::string MediaStreamManager::AddRequest(DeviceRequest* request) {
return unique_label;
}
-void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) {
+MediaStreamManager::DeviceRequest*
+MediaStreamManager::FindRequest(const std::string& label) const {
+ DeviceRequests::const_iterator request_it = requests_.find(label);
+ return request_it == requests_.end() ? NULL : request_it->second;
+}
+
+void MediaStreamManager::DeleteRequest(const std::string& label) {
+ DeviceRequests::iterator it = requests_.find(label);
+ scoped_ptr<DeviceRequest> request(it->second);
requests_.erase(it);
}
-void MediaStreamManager::PostRequestToUI(const std::string& label) {
+void MediaStreamManager::PostRequestToUI(const std::string& label,
+ DeviceRequest* request) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DeviceRequest* request = requests_[label];
+ DVLOG(1) << "PostRequestToUI({label= " << label << "})";
+ // If a specific device has been requested we need to find the real device id.
+ if (!TranslateRequestedSourceIdToDeviceId(request)) {
+ FinalizeRequestFailed(label, request);
+ return;
+ }
+
+ const MediaStreamType audio_type = request->request.audio_type;
+ const MediaStreamType video_type = request->request.video_type;
+
+ // Post the request to UI and set the state.
+ if (IsAudioMediaType(audio_type))
+ request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
+ if (IsVideoMediaType(video_type))
+ request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
if (use_fake_ui_) {
if (!fake_ui_)
@@ -741,9 +798,20 @@ void MediaStreamManager::PostRequestToUI(const std::string& label) {
base::Unretained(this), label));
}
-void MediaStreamManager::HandleRequest(const std::string& label) {
+void MediaStreamManager::SetupRequest(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DeviceRequest* request = requests_[label];
+ DeviceRequest* request = FindRequest(label);
+ if (!request) {
+ DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!";
+ return; // This can happen if the request has been canceled.
+ }
+
+ if (!request->request.security_origin.is_valid()) {
+ LOG(ERROR) << "Invalid security origin. "
+ << request->request.security_origin;
+ FinalizeRequestFailed(label, request);
+ return;
+ }
const MediaStreamType audio_type = request->request.audio_type;
const MediaStreamType video_type = request->request.video_type;
@@ -751,9 +819,17 @@ void MediaStreamManager::HandleRequest(const std::string& label) {
bool is_web_contents_capture =
audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
video_type == MEDIA_TAB_VIDEO_CAPTURE;
+ if (is_web_contents_capture && !SetupTabCaptureRequest(request)) {
+ FinalizeRequestFailed(label, request);
+ return;
+ }
bool is_screen_capture =
video_type == MEDIA_DESKTOP_VIDEO_CAPTURE;
+ if (is_screen_capture && !SetupScreenCaptureRequest(request)) {
+ FinalizeRequestFailed(label, request);
+ return;
+ }
if (!is_web_contents_capture &&
!is_screen_capture &&
@@ -763,38 +839,102 @@ void MediaStreamManager::HandleRequest(const std::string& label) {
StartEnumeration(request);
return;
}
+ PostRequestToUI(label, request);
+}
- // No need to do new device enumerations, post the request to UI
- // immediately.
- if (IsAudioMediaType(audio_type))
- request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
- if (IsVideoMediaType(video_type))
- request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
+bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
+ DCHECK(request->request.audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
+ request->request.video_type == MEDIA_TAB_VIDEO_CAPTURE);
- PostRequestToUI(label);
+ MediaStreamRequest* ms_request = &request->request;
+ // Customize options for a WebContents based capture.
+ int target_render_process_id = 0;
+ int target_render_view_id = 0;
+
+ // TODO(justinlin): Can't plumb audio mirroring using stream type right
+ // now, so plumbing by device_id. Will revisit once it's refactored.
+ // http://crbug.com/163100
+ std::string tab_capture_device_id =
+ WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
+ !ms_request->requested_video_device_id.empty() ?
+ ms_request->requested_video_device_id :
+ ms_request->requested_audio_device_id);
+
+ bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
+ tab_capture_device_id, &target_render_process_id,
+ &target_render_view_id);
+ if (!has_valid_device_id ||
+ (ms_request->audio_type != MEDIA_TAB_AUDIO_CAPTURE &&
+ ms_request->audio_type != MEDIA_NO_SERVICE) ||
+ (ms_request->video_type != MEDIA_TAB_VIDEO_CAPTURE &&
+ ms_request->video_type != MEDIA_NO_SERVICE)) {
+ return false;
+ }
+ ms_request->tab_capture_device_id = tab_capture_device_id;
+ ms_request->render_process_id = target_render_process_id;
+ ms_request->render_view_id = target_render_view_id;
+ DVLOG(3) << "SetupTabCaptureRequest "
+ << ", {tab_capture_device_id = " << tab_capture_device_id << "}"
+ << ", {target_render_process_id = " << target_render_process_id
+ << "}"
+ << ", {target_render_view_id = " << target_render_view_id << "}";
+ return true;
+}
+
+bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) {
+ DCHECK(request->request.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE ||
+ request->request.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE);
+ const MediaStreamRequest& ms_request = request->request;
+
+ // For screen capture we only support two valid combinations:
+ // (1) screen video capture only, or
+ // (2) screen video capture with loopback audio capture.
+ if (ms_request.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE ||
+ (ms_request.audio_type != MEDIA_NO_SERVICE &&
+ ms_request.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) {
+ // TODO(sergeyu): Surface error message to the calling JS code.
+ LOG(ERROR) << "Invalid screen capture request.";
+ return false;
+ }
+ return true;
+}
+
+StreamDeviceInfoArray MediaStreamManager::GetDevicesOpenedByRequest(
+ const std::string& label) const {
+ DeviceRequest* request = FindRequest(label);
+ if (!request)
+ return StreamDeviceInfoArray();
+ return request->devices;
}
bool MediaStreamManager::FindExistingRequestedDeviceInfo(
- int render_process_id,
- int render_view_id,
- MediaStreamRequestType type,
- const std::string& device_id,
- StreamDeviceInfo* device_info,
- MediaRequestState* request_state) const {
- DCHECK(device_info);
- DCHECK(request_state);
+ const DeviceRequest& new_request,
+ const MediaStreamDevice& new_device_info,
+ StreamDeviceInfo* existing_device_info,
+ MediaRequestState* existing_request_state) const {
+ DCHECK(existing_device_info);
+ DCHECK(existing_request_state);
+
+ const MediaStreamRequest& new_ms_request = new_request.request;
+
+ std::string source_id = content::GetHMACForMediaDeviceID(
+ new_request.resource_context,
+ new_ms_request.security_origin,
+ new_device_info.id);
+
for (DeviceRequests::const_iterator it = requests_.begin();
it != requests_.end() ; ++it) {
const DeviceRequest* request = it->second;
- if (request->requesting_process_id ==render_process_id &&
- request->requesting_view_id == render_view_id &&
- request->request.request_type == type) {
+ if (request->requesting_process_id == new_request.requesting_process_id &&
+ request->requesting_view_id == new_request.requesting_view_id &&
+ request->request.request_type == new_ms_request.request_type) {
for (StreamDeviceInfoArray::const_iterator device_it =
request->devices.begin();
device_it != request->devices.end(); ++device_it) {
- if (device_it->device.id == device_id) {
- *device_info = *device_it;
- *request_state = request->state(device_it->device.type);
+ if (device_it->device.id == source_id &&
+ device_it->device.type == new_device_info.type) {
+ *existing_device_info = *device_it;
+ *existing_request_state = request->state(device_it->device.type);
return true;
}
}
@@ -803,6 +943,72 @@ bool MediaStreamManager::FindExistingRequestedDeviceInfo(
return false;
}
+void MediaStreamManager::FinalizeGenerateStream(const std::string& label,
+ DeviceRequest* request) {
+ DVLOG(1) << "FinalizeGenerateStream label " << label;
+ const StreamDeviceInfoArray& requested_devices = request->devices;
+
+ // Partition the array of devices into audio vs video.
+ StreamDeviceInfoArray audio_devices, video_devices;
+ for (StreamDeviceInfoArray::const_iterator device_it =
+ requested_devices.begin();
+ device_it != requested_devices.end(); ++device_it) {
+ if (IsAudioMediaType(device_it->device.type)) {
+ audio_devices.push_back(*device_it);
+ } else if (IsVideoMediaType(device_it->device.type)) {
+ video_devices.push_back(*device_it);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ request->requester->StreamGenerated(label, audio_devices, video_devices);
+}
+
+void MediaStreamManager::FinalizeRequestFailed(
+ const std::string& label,
+ DeviceRequest* request) {
+ if (request->requester)
+ request->requester->StreamGenerationFailed(label);
+
+ if (request->request.request_type == MEDIA_DEVICE_ACCESS &&
+ !request->callback.is_null()) {
+ request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass());
+ }
+
+ DeleteRequest(label);
+}
+
+void MediaStreamManager::FinalizeOpenDevice(const std::string& label,
+ DeviceRequest* request) {
+ const StreamDeviceInfoArray& requested_devices = request->devices;
+ request->requester->DeviceOpened(label, requested_devices.front());
+}
+
+void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label,
+ DeviceRequest* request) {
+ if (!request->request.security_origin.is_valid()) {
+ request->requester->DevicesEnumerated(label, StreamDeviceInfoArray());
+ return;
+ }
+ for (StreamDeviceInfoArray::iterator it = request->devices.begin();
+ it != request->devices.end(); ++it) {
+ TranslateDeviceIdToSourceId(request, &it->device);
+ }
+ request->requester->DevicesEnumerated(label, request->devices);
+}
+
+void MediaStreamManager::FinalizeMediaAccessRequest(
+ const std::string& label,
+ DeviceRequest* request,
+ const MediaStreamDevices& devices) {
+ if (!request->callback.is_null())
+ request->callback.Run(devices, request->ui_proxy.Pass());
+
+ // Delete the request since it is done.
+ DeleteRequest(label);
+}
+
void MediaStreamManager::InitializeDeviceManagersOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (device_thread_)
@@ -858,7 +1064,6 @@ void MediaStreamManager::Opened(MediaStreamType stream_type,
const StreamDeviceInfo* info =
audio_input_device_manager_->GetOpenedDeviceInfoById(
device_it->session_id);
- DCHECK_EQ(info->device.id, device_it->device.id);
device_it->device.input = info->device.input;
device_it->device.matched_output = info->device.matched_output;
}
@@ -877,27 +1082,12 @@ void MediaStreamManager::HandleRequestDone(const std::string& label,
DVLOG(1) << "HandleRequestDone("
<< ", {label = " << label << "})";
- const StreamDeviceInfoArray& requested_devices = request->devices;
switch (request->request.request_type) {
case MEDIA_OPEN_DEVICE:
- request->requester->DeviceOpened(label, requested_devices.front());
+ FinalizeOpenDevice(label, request);
break;
case MEDIA_GENERATE_STREAM: {
- // Partition the array of devices into audio vs video.
- StreamDeviceInfoArray audio_devices, video_devices;
- for (StreamDeviceInfoArray::const_iterator device_it =
- requested_devices.begin();
- device_it != requested_devices.end(); ++device_it) {
- if (IsAudioMediaType(device_it->device.type)) {
- audio_devices.push_back(*device_it);
- } else if (IsVideoMediaType(device_it->device.type)) {
- video_devices.push_back(*device_it);
- } else {
- NOTREACHED();
- }
- }
-
- request->requester->StreamGenerated(label, audio_devices, video_devices);
+ FinalizeGenerateStream(label, request);
break;
}
default:
@@ -940,10 +1130,7 @@ void MediaStreamManager::DevicesEnumerated(
// for example, when the machine just wakes up from sleep. We set the cache
// to be invalid so that the next media request will trigger the
// enumeration again. See issue/317673.
- if (devices.size())
- cache->valid = true;
- else
- cache->valid = false;
+ cache->valid = !devices.empty();
}
if (need_update_clients && monitoring_started_)
@@ -965,11 +1152,13 @@ void MediaStreamManager::DevicesEnumerated(
}
for (std::list<std::string>::iterator it = label_list.begin();
it != label_list.end(); ++it) {
- DeviceRequest* request = requests_[*it];
+ DeviceRequest* request = FindRequest(*it);
switch (request->request.request_type) {
case MEDIA_ENUMERATE_DEVICES:
- if (need_update_clients && request->requester)
- request->requester->DevicesEnumerated(*it, devices);
+ if (need_update_clients && request->requester) {
+ request->devices = devices;
+ FinalizeEnumerateDevices(*it, request);
+ }
break;
default:
if (request->state(request->request.audio_type) ==
@@ -982,8 +1171,7 @@ void MediaStreamManager::DevicesEnumerated(
break;
}
- // Post the request to UI for permission approval.
- PostRequestToUI(*it);
+ PostRequestToUI(*it, request);
break;
}
}
@@ -999,39 +1187,24 @@ void MediaStreamManager::HandleAccessRequestResponse(
DVLOG(1) << "HandleAccessRequestResponse("
<< ", {label = " << label << "})";
- DeviceRequests::iterator request_it = requests_.find(label);
- if (request_it == requests_.end()) {
+ DeviceRequest* request = FindRequest(label);
+ if (!request) {
+ // The request has been canceled before the UI returned.
return;
}
- // Handle the case when the request was denied.
- if (devices.empty()) {
- // Notify the users about the request result.
- scoped_ptr<DeviceRequest> request(request_it->second);
- if (request->requester)
- request->requester->StreamGenerationFailed(label);
-
- if (request->request.request_type == MEDIA_DEVICE_ACCESS &&
- !request->callback.is_null()) {
- request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass());
- }
-
- RemoveRequest(request_it);
+ if (request->request.request_type == MEDIA_DEVICE_ACCESS) {
+ FinalizeMediaAccessRequest(label, request, devices);
return;
}
- if (request_it->second->request.request_type == MEDIA_DEVICE_ACCESS) {
- scoped_ptr<DeviceRequest> request(request_it->second);
- if (!request->callback.is_null())
- request->callback.Run(devices, request->ui_proxy.Pass());
-
- // Delete the request since it is done.
- RemoveRequest(request_it);
+ // Handle the case when the request was denied.
+ if (devices.empty()) {
+ FinalizeRequestFailed(label, request);
return;
}
// Process all newly-accepted devices for this request.
- DeviceRequest* request = request_it->second;
bool found_audio = false;
bool found_video = false;
for (MediaStreamDevices::const_iterator device_it = devices.begin();
@@ -1072,30 +1245,29 @@ void MediaStreamManager::HandleAccessRequestResponse(
// per render view. This is so that the permission to use a device can be
// revoked by a single call to StopStreamDevice regardless of how many
// MediaStreams it is being used in.
-
if (request->request.request_type == MEDIA_GENERATE_STREAM) {
MediaRequestState state;
- if (FindExistingRequestedDeviceInfo(request->requesting_process_id,
- request->requesting_view_id,
- request->request.request_type,
- device_it->id,
+ if (FindExistingRequestedDeviceInfo(*request,
+ device_info.device,
&device_info,
&state)) {
request->devices.push_back(device_info);
request->SetState(device_info.device.type, state);
DVLOG(1) << "HandleAccessRequestResponse - device already opened "
- << ", {label = " << label << "}"
- << ", device_id = " << device_it->id << "}";
+ << ", {label = " << label << "}"
+ << ", device_id = " << device_it->id << "}";
continue;
}
}
device_info.session_id =
GetDeviceManager(device_info.device.type)->Open(device_info);
+ TranslateDeviceIdToSourceId(request, &device_info.device);
request->devices.push_back(device_info);
+
request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING);
DVLOG(1) << "HandleAccessRequestResponse - opening device "
<< ", {label = " << label << "}"
- << ", {device_id = " << device_it->id << "}"
+ << ", {device_id = " << device_info.device.id << "}"
<< ", {session_id = " << device_info.session_id << "}";
}
@@ -1115,11 +1287,10 @@ void MediaStreamManager::HandleAccessRequestResponse(
void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DeviceRequests::iterator it = requests_.find(label);
- if (it == requests_.end())
+ DeviceRequest* request = FindRequest(label);
+ if (!request)
return;
- DeviceRequest* request = it->second;
// Notify renderers that the devices in the stream will be stopped.
if (request->requester) {
for (StreamDeviceInfoArray::iterator device_it = request->devices.begin();
@@ -1146,6 +1317,7 @@ void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) {
}
void MediaStreamManager::WillDestroyCurrentMessageLoop() {
+ DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()";
DCHECK_EQ(base::MessageLoop::current(), io_loop_);
DCHECK(requests_.empty());
if (device_thread_) {
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index d1b6ec245d..db99cd5371 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -51,6 +51,7 @@ class FakeMediaStreamUIProxy;
class MediaStreamDeviceSettings;
class MediaStreamRequester;
class MediaStreamUIProxy;
+class ResourceContext;
class VideoCaptureManager;
// MediaStreamManager is used to generate and close new media devices, not to
@@ -96,6 +97,7 @@ class CONTENT_EXPORT MediaStreamManager
std::string GenerateStream(MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
const StreamOptions& components,
const GURL& security_origin);
@@ -119,6 +121,7 @@ class CONTENT_EXPORT MediaStreamManager
virtual std::string EnumerateDevices(MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
MediaStreamType type,
const GURL& security_origin);
@@ -129,11 +132,16 @@ class CONTENT_EXPORT MediaStreamManager
std::string OpenDevice(MediaStreamRequester* requester,
int render_process_id,
int render_view_id,
+ ResourceContext* rc,
int page_request_id,
const std::string& device_id,
MediaStreamType type,
const GURL& security_origin);
+ // Called by UI to make sure the device monitor is started so that UI receive
+ // notifications about device changes.
+ void EnsureDeviceMonitorStarted();
+
// Implements MediaStreamProviderListener.
virtual void Opened(MediaStreamType stream_type,
int capture_session_id) OVERRIDE;
@@ -155,12 +163,19 @@ class CONTENT_EXPORT MediaStreamManager
// generated stream (or when using --use-fake-ui-for-media-stream).
void UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui);
+ // Returns all devices currently opened by a request with label |label|.
+ // If no request with |label| exist, an empty array is returned.
+ StreamDeviceInfoArray GetDevicesOpenedByRequest(
+ const std::string& label) const;
+
// This object gets deleted on the UI thread after the IO thread has been
// destroyed. So we need to know when IO thread is being destroyed so that
- // we can delete VideoCaptureManager and AudioInputDeviceManager.
- // We also must call this function explicitly in tests which use
- // TestBrowserThreadBundle, because the notification happens too late in that
- // case (see http://crbug.com/247525#c14).
+ // we can delete VideoCaptureManager and AudioInputDeviceManager. Normally
+ // this is handled by
+ // base::MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop.
+ // But for some tests which use TestBrowserThreadBundle, we need to call
+ // WillDestroyCurrentMessageLoop explicitly because the notification happens
+ // too late. (see http://crbug.com/247525#c14).
virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
protected:
@@ -168,8 +183,6 @@ class CONTENT_EXPORT MediaStreamManager
MediaStreamManager();
private:
- friend class MockMediaStreamDispatcherHost;
-
// Contains all data needed to keep track of requests.
class DeviceRequest;
@@ -193,11 +206,12 @@ class CONTENT_EXPORT MediaStreamManager
void NotifyDevicesChanged(MediaStreamType stream_type,
const StreamDeviceInfoArray& devices);
-
void HandleAccessRequestResponse(const std::string& label,
const MediaStreamDevices& devices);
void StopMediaStreamFromBrowser(const std::string& label);
+ void DoEnumerateDevices(const std::string& label);
+
// Helpers.
// Checks if all devices that was requested in the request identififed by
// |label| has been opened and set the request state accordingly.
@@ -216,23 +230,39 @@ class CONTENT_EXPORT MediaStreamManager
MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type);
void StartEnumeration(DeviceRequest* request);
std::string AddRequest(DeviceRequest* request);
- void RemoveRequest(DeviceRequests::iterator it);
+ DeviceRequest* FindRequest(const std::string& label) const;
+ void DeleteRequest(const std::string& label);
void ClearEnumerationCache(EnumerationCache* cache);
- void PostRequestToUI(const std::string& label);
- void HandleRequest(const std::string& label);
- // Returns true if a device with |device_id| has already been requested by
- // |render_process_id| and |render_view_id| of type |type|. If it has been
- // requested, |device_info| contain information about the the device.
- bool FindExistingRequestedDeviceInfo(int render_process_id,
- int render_view_id,
- MediaStreamRequestType type,
- const std::string& device_id,
- StreamDeviceInfo* device_info,
- MediaRequestState* request_state) const;
-
- // Sends cached device list to a client corresponding to the request
- // identified by |label|.
- void SendCachedDeviceList(EnumerationCache* cache, const std::string& label);
+ // Prepare the request with label |label| by starting device enumeration if
+ // needed.
+ void SetupRequest(const std::string& label);
+ bool SetupTabCaptureRequest(DeviceRequest* request);
+ bool SetupScreenCaptureRequest(DeviceRequest* request);
+ // Called when a request has been setup and devices have been enumerated if
+ // needed. If a certain source id has been requested, the source id is
+ // translated to a real device id before the request is posted to UI.
+ void PostRequestToUI(const std::string& label, DeviceRequest* request);
+ // Returns true if a device with |device_id| has already been requested with
+ // a render procecss_id and render_view_id and type equal to the the values
+ // in |request|. If it has been requested, |device_info| contain information
+ // about the device.
+ bool FindExistingRequestedDeviceInfo(
+ const DeviceRequest& new_request,
+ const MediaStreamDevice& new_device_info,
+ StreamDeviceInfo* existing_device_info,
+ MediaRequestState* existing_request_state) const;
+
+ void FinalizeGenerateStream(const std::string& label,
+ DeviceRequest* request);
+ void FinalizeRequestFailed(const std::string& label,
+ DeviceRequest* request);
+ void FinalizeOpenDevice(const std::string& label,
+ DeviceRequest* request);
+ void FinalizeMediaAccessRequest(const std::string& label,
+ DeviceRequest* request,
+ const MediaStreamDevices& devices);
+ void FinalizeEnumerateDevices(const std::string& label,
+ DeviceRequest* request);
// This method is called when an audio or video device is plugged in or
// removed. It make sure all MediaStreams that use a removed device is
@@ -249,14 +279,19 @@ class CONTENT_EXPORT MediaStreamManager
void StartMonitoring();
void StopMonitoring();
- // Finds and returns the raw device id corresponding to the given
- // |device_guid|. Returns true if there was a raw device id that matched the
- // given |device_guid|, false if nothing matched it.
- bool TranslateGUIDToRawId(
+ bool TranslateRequestedSourceIdToDeviceId(DeviceRequest* request);
+ void TranslateDeviceIdToSourceId(DeviceRequest* request,
+ MediaStreamDevice* device);
+
+ // Finds and returns the device id corresponding to the given
+ // |source_id|. Returns true if there was a raw device id that matched the
+ // given |source_id|, false if nothing matched it.
+ bool TranslateSourceIdToDeviceId(
MediaStreamType stream_type,
+ ResourceContext* rc,
const GURL& security_origin,
- const std::string& device_guid,
- std::string* raw_device_id);
+ const std::string& source_id,
+ std::string* device_id);
// Device thread shared by VideoCaptureManager and AudioInputDeviceManager.
scoped_ptr<base::Thread> device_thread_;
@@ -280,15 +315,10 @@ class CONTENT_EXPORT MediaStreamManager
// All non-closed request.
DeviceRequests requests_;
- std::vector<int> opened_audio_session_ids_;
- std::vector<int> opened_video_session_ids_;
-
// Hold a pointer to the IO loop to check we delete the device thread and
// managers on the right thread.
base::MessageLoop* io_loop_;
- bool screen_capture_active_;
-
bool use_fake_ui_;
scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 03e95e0b66..f4f0b2090e 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -13,6 +13,10 @@
#include "content/common/media/media_stream_options.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/audio_manager_base.h"
+#include "media/audio/fake_audio_log_factory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
#if defined(USE_ALSA)
#include "media/audio/alsa/audio_manager_alsa.h"
#elif defined(OS_ANDROID)
@@ -24,8 +28,6 @@
#else
#include "media/audio/fake_audio_manager.h"
#endif
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
@@ -49,7 +51,7 @@ typedef media::FakeAudioManager AudioManagerPlatform;
// the buildbots. media::AudioManagerBase
class MockAudioManager : public AudioManagerPlatform {
public:
- MockAudioManager() {}
+ MockAudioManager() : AudioManagerPlatform(&fake_audio_log_factory_) {}
virtual ~MockAudioManager() {}
virtual void GetAudioInputDeviceNames(
@@ -64,6 +66,7 @@ class MockAudioManager : public AudioManagerPlatform {
}
private:
+ media::FakeAudioLogFactory fake_audio_log_factory_;
DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
};
@@ -81,7 +84,6 @@ class MediaStreamManagerTest : public ::testing::Test {
}
virtual ~MediaStreamManagerTest() {
- media_stream_manager_->WillDestroyCurrentMessageLoop();
}
MOCK_METHOD1(Response, void(int index));
@@ -133,6 +135,8 @@ TEST_F(MediaStreamManagerTest, MakeAndCancelMediaAccessRequest) {
std::string label = MakeMediaAccessRequest(0);
// No callback is expected.
media_stream_manager_->CancelRequest(label);
+ run_loop_.RunUntilIdle();
+ media_stream_manager_->WillDestroyCurrentMessageLoop();
}
TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 3e4edbc0ac..b91ccb1209 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -193,12 +193,16 @@ void FakeMediaStreamUIProxy::RequestAccess(
it != devices_.end(); ++it) {
if (!accepted_audio &&
IsAudioMediaType(request.audio_type) &&
- IsAudioMediaType(it->type)) {
+ IsAudioMediaType(it->type) &&
+ (request.requested_audio_device_id.empty() ||
+ request.requested_audio_device_id == it->id)) {
devices_to_use.push_back(*it);
accepted_audio = true;
} else if (!accepted_video &&
IsVideoMediaType(request.video_type) &&
- IsVideoMediaType(it->type)) {
+ IsVideoMediaType(it->type) &&
+ (request.requested_video_device_id.empty() ||
+ request.requested_video_device_id == it->id)) {
devices_to_use.push_back(*it);
accepted_video = true;
}
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 82219a6e87..bff55c618c 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -92,7 +92,7 @@ MATCHER_P(SameRequest, expected, "") {
}
TEST_F(MediaStreamUIProxyTest, Deny) {
- MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
+ MediaStreamRequest request(0, 0, 0, GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
@@ -118,7 +118,7 @@ TEST_F(MediaStreamUIProxyTest, Deny) {
}
TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
- MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
+ MediaStreamRequest request(0, 0, 0, GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
@@ -152,7 +152,7 @@ TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
// Verify that the proxy can be deleted before the request is processed.
TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
- MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
+ MediaStreamRequest request(0, 0, 0, GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
@@ -174,7 +174,7 @@ TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
}
TEST_F(MediaStreamUIProxyTest, StopFromUI) {
- MediaStreamRequest request(0, 0, 0, std::string(), GURL("http://origin/"),
+ MediaStreamRequest request(0, 0, 0, GURL("http://origin/"),
MEDIA_GENERATE_STREAM, std::string(),
std::string(),
MEDIA_DEVICE_AUDIO_CAPTURE,
diff --git a/content/browser/renderer_host/media/midi_host.cc b/content/browser/renderer_host/media/midi_host.cc
index 934d5a21f1..d6781f61df 100644
--- a/content/browser/renderer_host/media/midi_host.cc
+++ b/content/browser/renderer_host/media/midi_host.cc
@@ -16,26 +16,41 @@
#include "content/public/browser/media_observer.h"
#include "content/public/browser/user_metrics.h"
#include "media/midi/midi_manager.h"
+#include "media/midi/midi_message_queue.h"
+#include "media/midi/midi_message_util.h"
using media::MIDIManager;
using media::MIDIPortInfoList;
+namespace content {
+namespace {
+
// The total number of bytes which we're allowed to send to the OS
// before knowing that they have been successfully sent.
-static const size_t kMaxInFlightBytes = 10 * 1024 * 1024; // 10 MB.
+const size_t kMaxInFlightBytes = 10 * 1024 * 1024; // 10 MB.
// We keep track of the number of bytes successfully sent to
// the hardware. Every once in a while we report back to the renderer
// the number of bytes sent since the last report. This threshold determines
// how many bytes will be sent before reporting back to the renderer.
-static const size_t kAcknowledgementThresholdBytes = 1024 * 1024; // 1 MB.
+const size_t kAcknowledgementThresholdBytes = 1024 * 1024; // 1 MB.
-static const uint8 kSysExMessage = 0xf0;
+const uint8 kSysExMessage = 0xf0;
+const uint8 kEndOfSysExMessage = 0xf7;
-namespace content {
+bool IsDataByte(uint8 data) {
+ return (data & 0x80) == 0;
+}
+
+bool IsSystemRealTimeMessage(uint8 data) {
+ return 0xf8 <= data && data <= 0xff;
+}
+
+} // namespace
MIDIHost::MIDIHost(int renderer_process_id, media::MIDIManager* midi_manager)
: renderer_process_id_(renderer_process_id),
+ has_sys_ex_permission_(false),
midi_manager_(midi_manager),
sent_bytes_in_flight_(0),
bytes_sent_since_last_acknowledgement_(0) {
@@ -75,6 +90,12 @@ void MIDIHost::OnStartSession(int client_id) {
if (success) {
input_ports = midi_manager_->input_ports();
output_ports = midi_manager_->output_ports();
+ received_messages_queues_.clear();
+ received_messages_queues_.resize(input_ports.size());
+ // ChildSecurityPolicy is set just before OnStartSession by
+ // MIDIDispatcherHost. So we can safely cache the policy.
+ has_sys_ex_permission_ = ChildProcessSecurityPolicyImpl::GetInstance()->
+ CanSendMIDISysExMessage(renderer_process_id_);
}
}
@@ -94,32 +115,26 @@ void MIDIHost::OnSendData(uint32 port,
if (data.empty())
return;
- base::AutoLock auto_lock(in_flight_lock_);
-
- // Sanity check that we won't send too much.
- if (sent_bytes_in_flight_ > kMaxInFlightBytes ||
- data.size() > kMaxInFlightBytes ||
- data.size() + sent_bytes_in_flight_ > kMaxInFlightBytes)
+ // Blink running in a renderer checks permission to raise a SecurityError
+ // in JavaScript. The actual permission check for security purposes
+ // happens here in the browser process.
+ if (!has_sys_ex_permission_ &&
+ (std::find(data.begin(), data.end(), kSysExMessage) != data.end())) {
+ RecordAction(UserMetricsAction("BadMessageTerminate_MIDI"));
+ BadMessageReceived();
return;
-
- if (data[0] >= kSysExMessage) {
- // Blink running in a renderer checks permission to raise a SecurityError in
- // JavaScript. The actual permission check for security perposes happens
- // here in the browser process.
- if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanSendMIDISysExMessage(
- renderer_process_id_)) {
- RecordAction(UserMetricsAction("BadMessageTerminate_MIDI"));
- BadMessageReceived();
- return;
- }
}
- midi_manager_->DispatchSendMIDIData(
- this,
- port,
- data,
- timestamp);
+ if (!IsValidWebMIDIData(data))
+ return;
+ base::AutoLock auto_lock(in_flight_lock_);
+ // Sanity check that we won't send too much data.
+ // TODO(yukawa): Consider to send an error event back to the renderer
+ // after some future discussion in W3C.
+ if (data.size() + sent_bytes_in_flight_ > kMaxInFlightBytes)
+ return;
+ midi_manager_->DispatchSendMIDIData(this, port, data, timestamp);
sent_bytes_in_flight_ += data.size();
}
@@ -130,20 +145,29 @@ void MIDIHost::ReceiveMIDIData(
double timestamp) {
TRACE_EVENT0("midi", "MIDIHost::ReceiveMIDIData");
- // Check a process security policy to receive a system exclusive message.
- if (length > 0 && data[0] >= kSysExMessage) {
- if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanSendMIDISysExMessage(
- renderer_process_id_)) {
- // MIDI devices may send a system exclusive messages even if the renderer
- // doesn't have a permission to receive it. Don't kill the renderer as
- // OnSendData() does.
- return;
- }
- }
+ if (received_messages_queues_.size() <= port)
+ return;
- // Send to the renderer.
- std::vector<uint8> v(data, data + length);
- Send(new MIDIMsg_DataReceived(port, v, timestamp));
+ // Lazy initialization
+ if (received_messages_queues_[port] == NULL)
+ received_messages_queues_[port] = new media::MIDIMessageQueue(true);
+
+ received_messages_queues_[port]->Add(data, length);
+ std::vector<uint8> message;
+ while (true) {
+ received_messages_queues_[port]->Get(&message);
+ if (message.empty())
+ break;
+
+ // MIDI devices may send a system exclusive messages even if the renderer
+ // doesn't have a permission to receive it. Don't kill the renderer as
+ // OnSendData() does.
+ if (message[0] == kSysExMessage && !has_sys_ex_permission_)
+ continue;
+
+ // Send to the renderer.
+ Send(new MIDIMsg_DataReceived(port, message, timestamp));
+ }
}
void MIDIHost::AccumulateMIDIBytesSent(size_t n) {
@@ -165,4 +189,37 @@ void MIDIHost::AccumulateMIDIBytesSent(size_t n) {
}
}
+// static
+bool MIDIHost::IsValidWebMIDIData(const std::vector<uint8>& data) {
+ bool in_sysex = false;
+ size_t waiting_data_length = 0;
+ for (size_t i = 0; i < data.size(); ++i) {
+ const uint8 current = data[i];
+ if (IsSystemRealTimeMessage(current))
+ continue; // Real time message can be placed at any point.
+ if (waiting_data_length > 0) {
+ if (!IsDataByte(current))
+ return false; // Error: |current| should have been data byte.
+ --waiting_data_length;
+ continue; // Found data byte as expected.
+ }
+ if (in_sysex) {
+ if (data[i] == kEndOfSysExMessage)
+ in_sysex = false;
+ else if (!IsDataByte(current))
+ return false; // Error: |current| should have been data byte.
+ continue; // Found data byte as expected.
+ }
+ if (current == kSysExMessage) {
+ in_sysex = true;
+ continue; // Found SysEX
+ }
+ waiting_data_length = media::GetMIDIMessageLength(current);
+ if (waiting_data_length == 0)
+ return false; // Error: |current| should have been a valid status byte.
+ --waiting_data_length; // Found status byte
+ }
+ return waiting_data_length == 0 && !in_sysex;
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/media/midi_host.h b/content/browser/renderer_host/media/midi_host.h
index e3b9df1b6b..153863fe60 100644
--- a/content/browser/renderer_host/media/midi_host.h
+++ b/content/browser/renderer_host/media/midi_host.h
@@ -7,8 +7,10 @@
#include <vector>
+#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
@@ -16,6 +18,7 @@
namespace media {
class MIDIManager;
+class MIDIMessageQueue;
}
namespace content {
@@ -33,11 +36,10 @@ class CONTENT_EXPORT MIDIHost
bool* message_was_ok) OVERRIDE;
// MIDIManagerClient implementation.
- virtual void ReceiveMIDIData(
- uint32 port,
- const uint8* data,
- size_t length,
- double timestamp) OVERRIDE;
+ virtual void ReceiveMIDIData(uint32 port,
+ const uint8* data,
+ size_t length,
+ double timestamp) OVERRIDE;
virtual void AccumulateMIDIBytesSent(size_t n) OVERRIDE;
// Start session to access MIDI hardware.
@@ -49,13 +51,25 @@ class CONTENT_EXPORT MIDIHost
double timestamp);
private:
+ FRIEND_TEST_ALL_PREFIXES(MIDIHostTest, IsValidWebMIDIData);
friend class base::DeleteHelper<MIDIHost>;
friend class BrowserThread;
virtual ~MIDIHost();
+ // Returns true if |data| fulfills the requirements of MIDIOutput.send API
+ // defined in the WebMIDI spec.
+ // - |data| must be any number of complete MIDI messages (data abbreviation
+ // called "running status" is disallowed).
+ // - 1-byte MIDI realtime messages can be placed at any position of |data|.
+ static bool IsValidWebMIDIData(const std::vector<uint8>& data);
+
int renderer_process_id_;
+ // Represents if the renderer has a permission to send/receive MIDI SysEX
+ // messages.
+ bool has_sys_ex_permission_;
+
// |midi_manager_| talks to the platform-specific MIDI APIs.
// It can be NULL if the platform (or our current implementation)
// does not support MIDI. If not supported then a call to
@@ -63,6 +77,9 @@ class CONTENT_EXPORT MIDIHost
// OnSendData() will do nothing.
media::MIDIManager* const midi_manager_;
+ // Buffers where data sent from each MIDI input port is stored.
+ ScopedVector<media::MIDIMessageQueue> received_messages_queues_;
+
// The number of bytes sent to the platform-specific MIDI sending
// system, but not yet completed.
size_t sent_bytes_in_flight_;
diff --git a/content/browser/renderer_host/media/midi_host_unittest.cc b/content/browser/renderer_host/media/midi_host_unittest.cc
new file mode 100644
index 0000000000..fedb4265b9
--- /dev/null
+++ b/content/browser/renderer_host/media/midi_host_unittest.cc
@@ -0,0 +1,90 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/midi_host.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+const uint8 kGMOn[] = { 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7 };
+const uint8 kGSOn[] = {
+ 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7,
+};
+const uint8 kNoteOn[] = { 0x90, 0x3c, 0x7f };
+const uint8 kNoteOnWithRunningStatus[] = {
+ 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f,
+};
+const uint8 kChannelPressure[] = { 0xd0, 0x01 };
+const uint8 kChannelPressureWithRunningStatus[] = {
+ 0xd0, 0x01, 0x01, 0x01,
+};
+const uint8 kTimingClock[] = { 0xf8 };
+const uint8 kBrokenData1[] = { 0x90 };
+const uint8 kBrokenData2[] = { 0xf7 };
+const uint8 kBrokenData3[] = { 0xf2, 0x00 };
+const uint8 kDataByte0[] = { 0x00 };
+
+template <typename T, size_t N>
+const std::vector<T> AsVector(const T(&data)[N]) {
+ std::vector<T> buffer;
+ buffer.insert(buffer.end(), data, data + N);
+ return buffer;
+}
+
+template <typename T, size_t N>
+void PushToVector(const T(&data)[N], std::vector<T>* buffer) {
+ buffer->insert(buffer->end(), data, data + N);
+}
+
+} // namespace
+
+TEST(MIDIHostTest, IsValidWebMIDIData) {
+ // Test single event scenario
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kGMOn)));
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kGSOn)));
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kNoteOn)));
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kChannelPressure)));
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kTimingClock)));
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(AsVector(kBrokenData1)));
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(AsVector(kBrokenData2)));
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(AsVector(kBrokenData3)));
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(AsVector(kDataByte0)));
+
+ // MIDI running status should be disallowed
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(
+ AsVector(kNoteOnWithRunningStatus)));
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(
+ AsVector(kChannelPressureWithRunningStatus)));
+
+ // Multiple messages are allowed as long as each of them is complete.
+ {
+ std::vector<uint8> buffer;
+ PushToVector(kGMOn, &buffer);
+ PushToVector(kNoteOn, &buffer);
+ PushToVector(kGSOn, &buffer);
+ PushToVector(kTimingClock, &buffer);
+ PushToVector(kNoteOn, &buffer);
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(buffer));
+ PushToVector(kBrokenData1, &buffer);
+ EXPECT_FALSE(MIDIHost::IsValidWebMIDIData(buffer));
+ }
+
+ // MIDI realtime message can be placed at any position.
+ {
+ const uint8 kNoteOnWithRealTimeClock[] = {
+ 0x90, 0xf8, 0x3c, 0x7f, 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8,
+ };
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(
+ AsVector(kNoteOnWithRealTimeClock)));
+
+ const uint8 kGMOnWithRealTimeClock[] = {
+ 0xf0, 0xf8, 0x7e, 0x7f, 0x09, 0x01, 0xf8, 0xf7,
+ };
+ EXPECT_TRUE(MIDIHost::IsValidWebMIDIData(AsVector(kGMOnWithRealTimeClock)));
+ }
+}
+
+} // namespace conent
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 6f1cbc0fb0..7581df39d5 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -346,7 +346,7 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
break;
case media::PIXEL_FORMAT_NV21:
DCHECK(!chopped_width && !chopped_height);
- origin_colorspace = libyuv::FOURCC_NV12;
+ origin_colorspace = libyuv::FOURCC_NV21;
break;
case media::PIXEL_FORMAT_YUY2:
DCHECK(!chopped_width && !chopped_height);
@@ -513,8 +513,20 @@ VideoCaptureController::VideoCaptureDeviceClient::DoReserveOutputBuffer(
if ((rotation % 180) == 0) {
rotated_buffers_.erase(buffer_id);
} else {
- if (rotated_buffers_.insert(buffer_id).second)
- memset(output_buffer->data(), 0, output_buffer->size());
+ if (rotated_buffers_.insert(buffer_id).second) {
+ scoped_refptr<media::VideoFrame> frame =
+ media::VideoFrame::WrapExternalPackedMemory(
+ media::VideoFrame::I420,
+ dimensions,
+ gfx::Rect(dimensions),
+ dimensions,
+ static_cast<uint8*>(output_buffer->data()),
+ output_buffer->size(),
+ base::SharedMemory::NULLHandle(),
+ base::TimeDelta(),
+ base::Closure());
+ media::FillYUV(frame, 0, 128, 128);
+ }
}
return output_buffer;
diff --git a/content/browser/renderer_host/media/video_capture_device_impl.cc b/content/browser/renderer_host/media/video_capture_device_impl.cc
index 54af30f71b..9b37b296c4 100644
--- a/content/browser/renderer_host/media/video_capture_device_impl.cc
+++ b/content/browser/renderer_host/media/video_capture_device_impl.cc
@@ -23,6 +23,7 @@
#include "content/public/browser/browser_thread.h"
#include "media/base/bind_to_loop.h"
#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
#include "media/video/capture/video_capture_types.h"
#include "ui/gfx/rect.h"
@@ -44,12 +45,18 @@ void DeleteCaptureMachineOnUIThread(
ThreadSafeCaptureOracle::ThreadSafeCaptureOracle(
scoped_ptr<media::VideoCaptureDevice::Client> client,
scoped_ptr<VideoCaptureOracle> oracle,
- const gfx::Size& capture_size,
- int frame_rate)
+ const media::VideoCaptureParams& params)
: client_(client.Pass()),
oracle_(oracle.Pass()),
- capture_size_(capture_size),
- frame_rate_(frame_rate) {}
+ params_(params),
+ capture_size_updated_(false) {
+ // Frame dimensions must each be an even integer since the client wants (or
+ // will convert to) YUV420.
+ capture_size_ = gfx::Size(
+ MakeEven(params.requested_format.frame_size.width()),
+ MakeEven(params.requested_format.frame_size.height()));
+ frame_rate_ = params.requested_format.frame_rate;
+}
ThreadSafeCaptureOracle::~ThreadSafeCaptureOracle() {}
@@ -122,6 +129,29 @@ bool ThreadSafeCaptureOracle::ObserveEventAndDecideCapture(
return true;
}
+void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
+ base::AutoLock guard(lock_);
+
+ // If this is the first call to UpdateCaptureSize(), or the receiver supports
+ // variable resolution, then determine the capture size by treating the
+ // requested width and height as maxima.
+ if (!capture_size_updated_ || params_.allow_resolution_change) {
+ // The capture resolution should not exceed the source frame size.
+ // In other words it should downscale the image but not upscale it.
+ if (source_size.width() > params_.requested_format.frame_size.width() ||
+ source_size.height() > params_.requested_format.frame_size.height()) {
+ gfx::Rect capture_rect = media::ComputeLetterboxRegion(
+ gfx::Rect(params_.requested_format.frame_size), source_size);
+ capture_size_ = gfx::Size(MakeEven(capture_rect.width()),
+ MakeEven(capture_rect.height()));
+ } else {
+ capture_size_ = gfx::Size(MakeEven(source_size.width()),
+ MakeEven(source_size.height()));
+ }
+ capture_size_updated_ = true;
+ }
+}
+
void ThreadSafeCaptureOracle::Stop() {
base::AutoLock guard(lock_);
client_.reset();
@@ -173,13 +203,10 @@ void VideoCaptureDeviceImpl::AllocateAndStart(
return;
}
- // Frame dimensions must each be a positive, even integer, since the client
- // wants (or will convert to) YUV420.
- gfx::Size frame_size(MakeEven(params.requested_format.frame_size.width()),
- MakeEven(params.requested_format.frame_size.height()));
- if (frame_size.width() < kMinFrameWidth ||
- frame_size.height() < kMinFrameHeight) {
- DVLOG(1) << "invalid frame size: " << frame_size.ToString();
+ if (params.requested_format.frame_size.width() < kMinFrameWidth ||
+ params.requested_format.frame_size.height() < kMinFrameHeight) {
+ DVLOG(1) << "invalid frame size: "
+ << params.requested_format.frame_size.ToString();
client->OnError();
return;
}
@@ -191,10 +218,7 @@ void VideoCaptureDeviceImpl::AllocateAndStart(
new VideoCaptureOracle(capture_period,
kAcceleratedSubscriberIsSupported));
oracle_proxy_ =
- new ThreadSafeCaptureOracle(client.Pass(),
- oracle.Pass(),
- frame_size,
- params.requested_format.frame_rate);
+ new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass(), params);
// Starts the capture machine asynchronously.
BrowserThread::PostTaskAndReplyWithResult(
diff --git a/content/browser/renderer_host/media/video_capture_device_impl.h b/content/browser/renderer_host/media/video_capture_device_impl.h
index ec771e8485..d9329b6aa4 100644
--- a/content/browser/renderer_host/media/video_capture_device_impl.h
+++ b/content/browser/renderer_host/media/video_capture_device_impl.h
@@ -45,8 +45,7 @@ class ThreadSafeCaptureOracle
public:
ThreadSafeCaptureOracle(scoped_ptr<media::VideoCaptureDevice::Client> client,
scoped_ptr<VideoCaptureOracle> oracle,
- const gfx::Size& capture_size,
- int frame_rate);
+ const media::VideoCaptureParams& params);
// Called when a captured frame is available or an error has occurred.
// If |success| is true then the frame provided is valid and |timestamp|
@@ -64,6 +63,10 @@ class ThreadSafeCaptureOracle
return oracle_->capture_period();
}
+ // Updates capture resolution based on the supplied source size and the
+ // maximum frame size.
+ void UpdateCaptureSize(const gfx::Size& source_size);
+
// Stop new captures from happening (but doesn't forget the client).
void Stop();
@@ -89,9 +92,15 @@ class ThreadSafeCaptureOracle
// Makes the decision to capture a frame.
const scoped_ptr<VideoCaptureOracle> oracle_;
+ // The video capture parameters used to construct the oracle proxy.
+ const media::VideoCaptureParams params_;
+
+ // Indicates if capture size has been updated after construction.
+ bool capture_size_updated_;
+
// The current capturing resolution and frame rate.
- const gfx::Size capture_size_;
- const int frame_rate_;
+ gfx::Size capture_size_;
+ int frame_rate_;
};
// Keeps track of the video capture source frames and executes copying on the
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc
index d56e005e10..1c169a4cd5 100644
--- a/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -20,7 +20,9 @@
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/common/media/video_capture_messages.h"
#include "content/public/test/mock_resource_context.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/test/test_content_browser_client.h"
#include "media/audio/audio_manager.h"
#include "media/base/video_frame.h"
#include "media/video/capture/video_capture_types.h"
@@ -58,7 +60,7 @@ class DumpVideo {
void StartDump(int width, int height) {
base::FilePath file_name = base::FilePath(base::StringPrintf(
FILE_PATH_LITERAL("dump_w%d_h%d.yuv"), width, height));
- file_.reset(file_util::OpenFile(file_name, "wb"));
+ file_.reset(base::OpenFile(file_name, "wb"));
expected_size_ = media::VideoFrame::AllocationSize(
media::VideoFrame::I420, gfx::Size(width, height));
}
@@ -243,8 +245,9 @@ class VideoCaptureHostTest : public testing::Test {
opened_session_id_(kInvalidMediaCaptureSessionId) {}
virtual void SetUp() OVERRIDE {
+ SetBrowserClientForTesting(&browser_client_);
// Create our own MediaStreamManager.
- audio_manager_.reset(media::AudioManager::Create());
+ audio_manager_.reset(media::AudioManager::CreateForTesting());
media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
#ifndef TEST_REAL_CAPTURE_DEVICE
media_stream_manager_->UseFakeDevice();
@@ -272,15 +275,13 @@ class VideoCaptureHostTest : public testing::Test {
// Release the reference to the mock object. The object will be destructed
// on the current message loop.
host_ = NULL;
-
- media_stream_manager_->WillDestroyCurrentMessageLoop();
}
void OpenSession() {
const int render_process_id = 1;
const int render_view_id = 1;
const int page_request_id = 1;
- const GURL security_origin;
+ const GURL security_origin("http://test.com");
ASSERT_TRUE(opened_device_label_.empty());
@@ -292,6 +293,7 @@ class VideoCaptureHostTest : public testing::Test {
&stream_requester_,
render_process_id,
render_view_id,
+ browser_context_.GetResourceContext(),
page_request_id,
MEDIA_DEVICE_VIDEO_CAPTURE,
security_origin);
@@ -314,6 +316,7 @@ class VideoCaptureHostTest : public testing::Test {
&stream_requester_,
render_process_id,
render_view_id,
+ browser_context_.GetResourceContext(),
page_request_id,
devices[0].device.id,
MEDIA_DEVICE_VIDEO_CAPTURE,
@@ -434,6 +437,8 @@ class VideoCaptureHostTest : public testing::Test {
scoped_ptr<media::AudioManager> audio_manager_;
scoped_ptr<MediaStreamManager> media_stream_manager_;
content::TestBrowserThreadBundle thread_bundle_;
+ content::TestBrowserContext browser_context_;
+ content::TestContentBrowserClient browser_client_;
scoped_refptr<base::MessageLoopProxy> message_loop_;
int opened_session_id_;
std::string opened_device_label_;
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 00fa52e43e..ff71016dc1 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -19,14 +19,16 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/desktop_media_id.h"
#include "content/public/common/media_stream_request.h"
+#include "media/base/media_switches.h"
#include "media/base/scoped_histogram_timer.h"
#include "media/video/capture/fake_video_capture_device.h"
+#include "media/video/capture/file_video_capture_device.h"
#include "media/video/capture/video_capture_device.h"
#if defined(ENABLE_SCREEN_CAPTURE)
#include "content/browser/renderer_host/media/desktop_capture_device.h"
#if defined(OS_CHROMEOS)
-#include "content/browser/renderer_host/media/desktop_capture_device_ash.h"
+#include "content/browser/renderer_host/media/desktop_capture_device_aura.h"
#endif
#endif
@@ -45,7 +47,7 @@ VideoCaptureManager::DeviceEntry::~DeviceEntry() {}
VideoCaptureManager::VideoCaptureManager()
: listener_(NULL),
new_capture_session_id_(1),
- use_fake_device_(false) {
+ artificial_device_source_for_testing_ (DISABLED) {
}
VideoCaptureManager::~VideoCaptureManager() {
@@ -131,7 +133,12 @@ void VideoCaptureManager::Close(int capture_session_id) {
}
void VideoCaptureManager::UseFakeDevice() {
- use_fake_device_ = true;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFileForFakeVideoCapture)) {
+ artificial_device_source_for_testing_ = Y4M_FILE;
+ } else {
+ artificial_device_source_for_testing_ = TEST_PATTERN;
+ }
}
void VideoCaptureManager::DoStartDeviceOnDeviceThread(
@@ -150,9 +157,20 @@ void VideoCaptureManager::DoStartDeviceOnDeviceThread(
media::VideoCaptureDevice::Name* found =
video_capture_devices_.FindById(entry->id);
if (found) {
- video_capture_device.reset(use_fake_device_ ?
- media::FakeVideoCaptureDevice::Create(*found) :
- media::VideoCaptureDevice::Create(*found));
+ switch (artificial_device_source_for_testing_) {
+ case DISABLED:
+ video_capture_device.reset(
+ media::VideoCaptureDevice::Create(*found));
+ break;
+ case TEST_PATTERN:
+ video_capture_device.reset(
+ media::FakeVideoCaptureDevice::Create(*found));
+ break;
+ case Y4M_FILE:
+ video_capture_device.reset(
+ media::FileVideoCaptureDevice::Create(*found));
+ break;
+ }
}
break;
}
@@ -167,7 +185,7 @@ void VideoCaptureManager::DoStartDeviceOnDeviceThread(
if (id.type != DesktopMediaID::TYPE_NONE) {
#if defined(OS_CHROMEOS)
// TODO(hshi): enable this path for Ash windows in metro mode.
- video_capture_device.reset(DesktopCaptureDeviceAsh::Create(id));
+ video_capture_device.reset(DesktopCaptureDeviceAura::Create(id));
#else
video_capture_device = DesktopCaptureDevice::Create(id);
#endif
@@ -320,10 +338,16 @@ VideoCaptureManager::GetAvailableDevicesOnDeviceThread(
// Cache the latest enumeration of video capture devices.
// We'll refer to this list again in OnOpen to avoid having to
// enumerate the devices again.
- if (!use_fake_device_) {
- media::VideoCaptureDevice::GetDeviceNames(&result);
- } else {
- media::FakeVideoCaptureDevice::GetDeviceNames(&result);
+ switch (artificial_device_source_for_testing_) {
+ case DISABLED:
+ media::VideoCaptureDevice::GetDeviceNames(&result);
+ break;
+ case TEST_PATTERN:
+ media::FakeVideoCaptureDevice::GetDeviceNames(&result);
+ break;
+ case Y4M_FILE:
+ media::FileVideoCaptureDevice::GetDeviceNames(&result);
+ break;
}
// TODO(nick): The correctness of device start depends on this cache being
diff --git a/content/browser/renderer_host/media/video_capture_manager.h b/content/browser/renderer_host/media/video_capture_manager.h
index 67dbb75373..82c61537dd 100644
--- a/content/browser/renderer_host/media/video_capture_manager.h
+++ b/content/browser/renderer_host/media/video_capture_manager.h
@@ -168,9 +168,15 @@ class CONTENT_EXPORT VideoCaptureManager : public MediaStreamProvider {
typedef std::set<DeviceEntry*> DeviceEntries;
DeviceEntries devices_;
- // Set to true if using fake video capture devices for testing, false by
- // default. This is only used for the MEDIA_DEVICE_VIDEO_CAPTURE device type.
- bool use_fake_device_;
+ // For unit testing and for performance/quality tests, a test device can be
+ // used instead of a real one. The device can be a simple fake device (a
+ // rolling pacman), or a file that is played in a loop continuously. This only
+ // applies to the MEDIA_DEVICE_VIDEO_CAPTURE device type.
+ enum {
+ DISABLED,
+ TEST_PATTERN,
+ Y4M_FILE
+ } artificial_device_source_for_testing_;
// We cache the enumerated video capture devices in
// GetAvailableDevicesOnDeviceThread() and then later look up the requested ID
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
index 5ef2ef9d87..34bb8334ae 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
@@ -16,7 +16,6 @@
#include "content/browser/renderer_host/media/web_contents_capture_util.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -24,6 +23,7 @@
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "media/base/video_util.h"
#include "media/base/yuv_convert.h"
@@ -228,13 +228,14 @@ class CaptureTestRenderViewHost : public TestRenderViewHost {
public:
CaptureTestRenderViewHost(SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
bool swapped_out,
CaptureTestSourceController* controller)
- : TestRenderViewHost(instance, delegate, widget_delegate, routing_id,
- main_frame_routing_id, swapped_out),
+ : TestRenderViewHost(instance, delegate, frame_delegate, widget_delegate,
+ routing_id, main_frame_routing_id, swapped_out),
controller_(controller) {
// Override the default view installed by TestRenderViewHost; we need
// our special subclass which has mocked-out tab capture support.
@@ -289,13 +290,15 @@ class CaptureTestRenderViewHostFactory : public RenderViewHostFactory {
virtual RenderViewHost* CreateRenderViewHost(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
bool swapped_out) OVERRIDE {
- return new CaptureTestRenderViewHost(instance, delegate, widget_delegate,
- routing_id, main_frame_routing_id,
- swapped_out, controller_);
+ return new CaptureTestRenderViewHost(instance, delegate, frame_delegate,
+ widget_delegate, routing_id,
+ main_frame_routing_id, swapped_out,
+ controller_);
}
private:
CaptureTestSourceController* controller_;
diff --git a/content/browser/renderer_host/native_web_keyboard_event_aura.cc b/content/browser/renderer_host/native_web_keyboard_event_aura.cc
index 1587bba1a8..c33f12ffc7 100644
--- a/content/browser/renderer_host/native_web_keyboard_event_aura.cc
+++ b/content/browser/renderer_host/native_web_keyboard_event_aura.cc
@@ -15,7 +15,7 @@ namespace {
// RenderViewHostDelegate::HandledKeybardEvent after the original aura
// event is destroyed.
ui::Event* CopyEvent(ui::Event* event) {
- return event ? static_cast<ui::KeyEvent*>(event)->Copy() : NULL;
+ return event ? new ui::KeyEvent(*static_cast<ui::KeyEvent*>(event)) : NULL;
}
int EventFlagsToWebInputEventModifiers(int flags) {
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.h b/content/browser/renderer_host/p2p/socket_dispatcher_host.h
index b2d76f468b..813da993b9 100644
--- a/content/browser/renderer_host/p2p/socket_dispatcher_host.h
+++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.h
@@ -11,9 +11,9 @@
#include <vector>
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
-#include "content/common/p2p_sockets.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_change_notifier.h"
diff --git a/content/browser/renderer_host/p2p/socket_host.h b/content/browser/renderer_host/p2p/socket_host.h
index 0ca8e0e36b..a11488451a 100644
--- a/content/browser/renderer_host/p2p/socket_host.h
+++ b/content/browser/renderer_host/p2p/socket_host.h
@@ -6,7 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_
#include "content/common/content_export.h"
-#include "content/common/p2p_sockets.h"
+#include "content/public/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "net/udp/datagram_socket.h"
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.cc b/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 3c890bba9f..2900541dcb 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -26,6 +26,8 @@ const int kPacketHeaderSize = sizeof(PacketLength);
const int kReadBufferSize = 4096;
const int kPacketLengthOffset = 2;
const int kTurnChannelDataHeaderSize = 4;
+const int kRecvSocketBufferSize = 128 * 1024;
+const int kSendSocketBufferSize = 128 * 1024;
bool IsTlsClientSocket(content::P2PSocketType type) {
return (type == content::P2P_SOCKET_STUN_TLS_CLIENT ||
@@ -198,6 +200,17 @@ void P2PSocketHostTcpBase::ProcessTlsSslConnectDone(int status) {
void P2PSocketHostTcpBase::OnOpen() {
state_ = STATE_OPEN;
+ // Setting socket send and receive buffer size.
+ if (!socket_->SetReceiveBufferSize(kRecvSocketBufferSize)) {
+ LOG(WARNING) << "Failed to set socket receive buffer size to "
+ << kRecvSocketBufferSize;
+ }
+
+ if (!socket_->SetSendBufferSize(kSendSocketBufferSize)) {
+ LOG(WARNING) << "Failed to set socket send buffer size to "
+ << kSendSocketBufferSize;
+ }
+
DoSendSocketCreateMsg();
DoRead();
}
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h
index 20de668dc1..b84efc7c28 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -13,7 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
-#include "content/common/p2p_sockets.h"
+#include "content/public/common/p2p_socket_type.h"
#include "net/base/completion_callback.h"
#include "net/base/ip_endpoint.h"
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server.h b/content/browser/renderer_host/p2p/socket_host_tcp_server.h
index 924e2d30e7..2581e83ee7 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp_server.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_server.h
@@ -13,7 +13,7 @@
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/content_export.h"
-#include "content/common/p2p_sockets.h"
+#include "content/public/common/p2p_socket_type.h"
#include "ipc/ipc_sender.h"
#include "net/base/completion_callback.h"
#include "net/socket/tcp_server_socket.h"
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc
index 6b433f46ff..8201ccb552 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -5,10 +5,12 @@
#include "content/browser/renderer_host/p2p/socket_host_udp.h"
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/stl_util.h"
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
#include "content/common/p2p_messages.h"
+#include "content/public/common/content_switches.h"
#include "ipc/ipc_sender.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -18,6 +20,8 @@ namespace {
// UDP packets cannot be bigger than 64k.
const int kReadBufferSize = 65536;
+// Socket receive buffer size.
+const int kRecvSocketBufferSize = 65536; // 64K
// Defines set of transient errors. These errors are ignored when we get them
// from sendto() or recvfrom() calls.
@@ -39,6 +43,11 @@ bool IsTransientError(int error) {
error == net::ERR_OUT_OF_MEMORY;
}
+bool AllowUDPWithoutSTUN() {
+ return CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableP2PSocketSTUNFilter);
+}
+
} // namespace
namespace content {
@@ -87,6 +96,12 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
return false;
}
+ // Setting recv socket buffer size.
+ if (!socket_->SetReceiveBufferSize(kRecvSocketBufferSize)) {
+ LOG(WARNING) << "Failed to set socket receive buffer size to "
+ << kRecvSocketBufferSize;
+ }
+
net::IPEndPoint address;
result = socket_->GetLocalAddress(&address);
if (result < 0) {
@@ -147,7 +162,7 @@ void P2PSocketHostUdp::HandleReadResult(int result) {
if (!ContainsKey(connected_peers_, recv_address_)) {
P2PSocketHost::StunMessageType type;
bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
- if (stun && IsRequestOrResponse(type)) {
+ if ((stun && IsRequestOrResponse(type)) || AllowUDPWithoutSTUN()) {
connected_peers_.insert(recv_address_);
} else if (!stun || type == STUN_DATA_INDICATION) {
LOG(ERROR) << "Received unexpected data packet from "
@@ -174,7 +189,7 @@ void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
return;
}
- if (!ContainsKey(connected_peers_, to)) {
+ if (!ContainsKey(connected_peers_, to) && !AllowUDPWithoutSTUN()) {
P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType();
bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
if (!stun || type == STUN_DATA_INDICATION) {
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.h b/content/browser/renderer_host/p2p/socket_host_udp.h
index ad0e354936..96b2244482 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.h
+++ b/content/browser/renderer_host/p2p/socket_host_udp.h
@@ -15,7 +15,7 @@
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/content_export.h"
-#include "content/common/p2p_sockets.h"
+#include "content/public/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "net/udp/udp_server_socket.h"
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 5657f47ac9..3ccacfc288 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -140,6 +140,11 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
return net::ERR_NOT_IMPLEMENTED;
}
+ virtual int SetMulticastInterface(uint32 interface_index) OVERRIDE {
+ NOTIMPLEMENTED();
+ return net::ERR_NOT_IMPLEMENTED;
+ }
+
virtual int SetMulticastTimeToLive(int time_to_live) OVERRIDE {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index a0f2f68cca..ec8b6edc46 100644
--- a/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -12,7 +12,6 @@
#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
-#include "content/browser/renderer_host/pepper/quota_file_io.h"
#include "content/common/fileapi/file_system_messages.h"
#include "content/common/sandbox_util.h"
#include "content/common/view_messages.h"
@@ -50,84 +49,6 @@ int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) {
return pp_error == PP_OK ? byte_number : pp_error;
}
-class QuotaFileIODelegate : public QuotaFileIO::Delegate {
- public:
- QuotaFileIODelegate(scoped_refptr<fileapi::FileSystemContext> context,
- int render_process_id)
- : context_(context),
- weak_factory_(this) { }
- virtual ~QuotaFileIODelegate() {}
-
- virtual void QueryAvailableSpace(
- const GURL& origin,
- quota::StorageType type,
- const AvailableSpaceCallback& callback) OVERRIDE {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- quota::QuotaManagerProxy* quota_manager_proxy =
- context_->quota_manager_proxy();
- DCHECK(quota_manager_proxy);
- if (!quota_manager_proxy) {
- callback.Run(0);
- return;
- }
- quota::QuotaManager* qm = quota_manager_proxy->quota_manager();
- DCHECK(qm);
- if (!qm) {
- callback.Run(0);
- return;
- }
- qm->GetUsageAndQuotaForWebApps(
- origin,
- type,
- base::Bind(&QuotaFileIODelegate::GotUsageAndQuotaForWebApps,
- weak_factory_.GetWeakPtr(), callback));
- }
-
- void GotUsageAndQuotaForWebApps(const AvailableSpaceCallback& callback,
- quota::QuotaStatusCode code,
- int64 usage,
- int64 quota) {
- if (code == quota::kQuotaStatusOk)
- callback.Run(std::max(static_cast<int64>(0), quota - usage));
- else
- callback.Run(0);
- }
-
- virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- fileapi::FileSystemURL url(context_->CrackURL(file_path));
- if (!url.is_valid())
- return;
- const fileapi::UpdateObserverList* observers =
- context_->GetUpdateObservers(url.type());
- if (!observers)
- return;
- observers->Notify(&fileapi::FileUpdateObserver::OnStartUpdate,
- MakeTuple(url));
- }
- virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- fileapi::FileSystemURL url(context_->CrackURL(file_path));
- if (!url.is_valid())
- return;
- const fileapi::UpdateObserverList* observers =
- context_->GetUpdateObservers(url.type());
- if (!observers)
- return;
- observers->Notify(&fileapi::FileUpdateObserver::OnUpdate,
- MakeTuple(url, delta));
- observers->Notify(&fileapi::FileUpdateObserver::OnEndUpdate,
- MakeTuple(url));
- }
- virtual scoped_refptr<base::MessageLoopProxy>
- GetFileThreadMessageLoopProxy() OVERRIDE {
- return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
- }
- private:
- scoped_refptr<fileapi::FileSystemContext> context_;
- base::WeakPtrFactory<QuotaFileIODelegate> weak_factory_;
-};
-
PepperFileIOHost::UIThreadStuff
GetUIThreadStuffForInternalFileSystems(int render_process_id) {
PepperFileIOHost::UIThreadStuff stuff;
@@ -168,9 +89,11 @@ PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host,
browser_ppapi_host_(host),
render_process_host_(NULL),
file_(base::kInvalidPlatformFileValue),
+ open_flags_(0),
file_system_type_(PP_FILESYSTEMTYPE_INVALID),
quota_policy_(quota::kQuotaLimitTypeUnknown),
- open_flags_(0),
+ max_written_offset_(0),
+ check_quota_(false),
weak_factory_(this) {
int unused;
if (!host->GetRenderViewIDsForInstance(instance,
@@ -251,7 +174,6 @@ int32_t PepperFileIOHost::OnHostMsgOpen(
render_process_id_,
file_system_url_))
return PP_ERROR_NOACCESS;
-
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI,
FROM_HERE,
@@ -298,6 +220,7 @@ void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems(
host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
return;
}
+
quota_policy_ = quota::kQuotaLimitTypeUnknown;
quota::QuotaManagerProxy* quota_manager_proxy =
file_system_context_->quota_manager_proxy();
@@ -325,8 +248,22 @@ void PepperFileIOHost::DidOpenInternalFile(
base::PlatformFileError result,
base::PlatformFile file,
const base::Closure& on_close_callback) {
- if (result == base::PLATFORM_FILE_OK)
+ if (result == base::PLATFORM_FILE_OK) {
on_close_callback_ = on_close_callback;
+
+ check_quota_ = file_system_host_ && file_system_host_->ChecksQuota();
+ if (check_quota_) {
+ file_system_host_->OpenQuotaFile(
+ this,
+ file_system_url_.path(),
+ base::Bind(&PepperFileIOHost::DidOpenQuotaFile,
+ weak_factory_.GetWeakPtr(),
+ reply_context,
+ file));
+ return;
+ }
+ }
+
ExecutePlatformOpenFileCallback(
reply_context, result, base::PassPlatformFile(&file), true);
}
@@ -378,26 +315,43 @@ int32_t PepperFileIOHost::OnHostMsgWrite(
FileIOStateManager::OPERATION_WRITE, true);
if (rv != PP_OK)
return rv;
+ if (offset < 0)
+ return PP_ERROR_BADARGUMENT;
- QuotaFileIO::WriteCallback cb =
- base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
- weak_factory_.GetWeakPtr(),
- context->MakeReplyMessageContext());
+ if (check_quota_) {
+ int64_t actual_offset =
+ (open_flags_ & PP_FILEOPENFLAG_APPEND) ? max_written_offset_ : offset;
- if (quota_file_io_) {
- if (!quota_file_io_->Write(offset, buffer.c_str(), buffer.size(), cb))
- return PP_ERROR_FAILED;
- } else {
- if (!base::FileUtilProxy::Write(
- file_message_loop_,
- file_,
- offset,
- buffer.c_str(),
- buffer.size(),
- cb))
- return PP_ERROR_FAILED;
+ uint64_t max_offset = actual_offset + buffer.size();
+ if (max_offset > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
+ return PP_ERROR_FAILED; // max_offset overflows.
+ int64_t amount = static_cast<int64_t>(max_offset) - max_written_offset_;
+
+ // Quota request amounts are restricted to 32 bits so we can use atomics
+ // when we move this code to the plugin side of the proxy.
+ if (amount > std::numeric_limits<int32_t>::max())
+ return PP_ERROR_NOQUOTA;
+
+ if (amount > 0) {
+ int32_t result = file_system_host_->RequestQuota(
+ static_cast<int32_t>(amount),
+ base::Bind(&PepperFileIOHost::GotWriteQuota,
+ weak_factory_.GetWeakPtr(),
+ context->MakeReplyMessageContext(),
+ offset, buffer));
+ if (result == PP_OK_COMPLETIONPENDING) {
+ state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE);
+ return result;
+ }
+ // RequestQuota returns either PP_OK_COMPLETIONPENDING or the requested
+ // quota amount.
+ DCHECK(result > 0);
+ }
}
+ if (!CallWrite(context->MakeReplyMessageContext(), offset, buffer))
+ return PP_ERROR_FAILED;
+
state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE);
return PP_OK_COMPLETIONPENDING;
}
@@ -409,20 +363,37 @@ int32_t PepperFileIOHost::OnHostMsgSetLength(
FileIOStateManager::OPERATION_EXCLUSIVE, true);
if (rv != PP_OK)
return rv;
+ if (length < 0)
+ return PP_ERROR_BADARGUMENT;
- base::FileUtilProxy::StatusCallback cb =
- base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
- weak_factory_.GetWeakPtr(),
- context->MakeReplyMessageContext());
-
- if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
- if (!quota_file_io_->SetLength(length, cb))
- return PP_ERROR_FAILED;
- } else {
- if (!base::FileUtilProxy::Truncate(file_message_loop_, file_, length, cb))
- return PP_ERROR_FAILED;
+ if (check_quota_) {
+ int64_t amount = length - max_written_offset_;
+ // Quota request amounts are restricted to 32 bits so we can use atomics
+ // when we move this code to the plugin side of the proxy.
+ if (amount > std::numeric_limits<int32_t>::max())
+ return PP_ERROR_NOQUOTA;
+
+ if (amount > 0) {
+ int32_t result = file_system_host_->RequestQuota(
+ static_cast<int32_t>(amount),
+ base::Bind(&PepperFileIOHost::GotSetLengthQuota,
+ weak_factory_.GetWeakPtr(),
+ context->MakeReplyMessageContext(),
+ length));
+ if (result == PP_OK_COMPLETIONPENDING) {
+ state_manager_.SetPendingOperation(
+ FileIOStateManager::OPERATION_EXCLUSIVE);
+ return result;
+ }
+ // RequestQuota returns either PP_OK_COMPLETIONPENDING or the requested
+ // quota amount.
+ DCHECK(result > 0);
+ }
}
+ if (!CallSetLength(context->MakeReplyMessageContext(), length))
+ return PP_ERROR_FAILED;
+
state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
return PP_OK_COMPLETIONPENDING;
}
@@ -448,6 +419,9 @@ int32_t PepperFileIOHost::OnHostMsgFlush(
int32_t PepperFileIOHost::OnHostMsgClose(
ppapi::host::HostMessageContext* context) {
+ if (check_quota_)
+ file_system_host_->CloseQuotaFile(this);
+
if (file_ != base::kInvalidPlatformFileValue) {
base::FileUtilProxy::Close(
file_message_loop_,
@@ -455,11 +429,84 @@ int32_t PepperFileIOHost::OnHostMsgClose(
base::Bind(&PepperFileIOHost::DidCloseFile,
weak_factory_.GetWeakPtr()));
file_ = base::kInvalidPlatformFileValue;
- quota_file_io_.reset();
}
return PP_OK;
}
+void PepperFileIOHost::DidOpenQuotaFile(
+ ppapi::host::ReplyMessageContext reply_context,
+ base::PlatformFile file,
+ int64_t max_written_offset) {
+ max_written_offset_ = max_written_offset;
+ DCHECK_LE(0, max_written_offset_);
+
+ ExecutePlatformOpenFileCallback(
+ reply_context, base::PLATFORM_FILE_OK, base::PassPlatformFile(&file),
+ true);
+}
+
+void PepperFileIOHost::GotWriteQuota(
+ ppapi::host::ReplyMessageContext reply_context,
+ int64_t offset,
+ const std::string& buffer,
+ int32_t granted) {
+ if (granted == 0) {
+ reply_context.params.set_result(PP_ERROR_NOQUOTA);
+ } else if (!CallWrite(reply_context, offset, buffer)) {
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ } else {
+ max_written_offset_ += granted;
+ return;
+ }
+ // Return the error result set above.
+ host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
+ state_manager_.SetOperationFinished();
+}
+
+void PepperFileIOHost::GotSetLengthQuota(
+ ppapi::host::ReplyMessageContext reply_context,
+ int64_t length,
+ int32_t granted) {
+ if (granted == 0) {
+ reply_context.params.set_result(PP_ERROR_NOQUOTA);
+ } else if (!CallSetLength(reply_context, length)) {
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ } else {
+ max_written_offset_ += granted;
+ return;
+ }
+ // Return the error result set above.
+ host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
+ state_manager_.SetOperationFinished();
+}
+
+bool PepperFileIOHost::CallWrite(
+ ppapi::host::ReplyMessageContext reply_context,
+ int64_t offset,
+ const std::string& buffer) {
+ return base::FileUtilProxy::Write(
+ file_message_loop_,
+ file_,
+ offset,
+ buffer.c_str(),
+ buffer.size(),
+ base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
+ weak_factory_.GetWeakPtr(),
+ reply_context));
+}
+
+bool PepperFileIOHost::CallSetLength(
+ ppapi::host::ReplyMessageContext reply_context,
+ int64_t length) {
+ return base::FileUtilProxy::Truncate(
+ file_message_loop_,
+ file_,
+ length,
+ base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
+ weak_factory_.GetWeakPtr(),
+ reply_context));
+}
+
void PepperFileIOHost::DidCloseFile(base::PlatformFileError error) {
// Silently ignore if we fail to close the file.
if (!on_close_callback_.is_null()) {
@@ -525,13 +572,7 @@ void PepperFileIOHost::ExecutePlatformOpenFileCallback(
DCHECK(file_ == base::kInvalidPlatformFileValue);
file_ = file.ReleaseValue();
- DCHECK(!quota_file_io_.get());
if (file_ != base::kInvalidPlatformFileValue) {
- if (ppapi::FileSystemTypeHasQuota(file_system_type_)) {
- quota_file_io_.reset(new QuotaFileIO(
- new QuotaFileIODelegate(file_system_context_, render_process_id_),
- file_, file_system_url_.ToGURL(), file_system_type_));
- }
int32_t flags_to_send = open_flags_;
if (!host()->permissions().HasPermission(ppapi::PERMISSION_DEV)) {
// IMPORTANT: Clear PP_FILEOPENFLAG_WRITE and PP_FILEOPENFLAG_APPEND so
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.h b/content/browser/renderer_host/pepper/pepper_file_io_host.h
index dd5d8dd527..1c5cfcda8e 100644
--- a/content/browser/renderer_host/pepper/pepper_file_io_host.h
+++ b/content/browser/renderer_host/pepper/pepper_file_io_host.h
@@ -23,11 +23,8 @@
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/common/quota/quota_types.h"
-using ppapi::host::ReplyMessageContext;
-
namespace content {
class PepperFileSystemBrowserHost;
-class QuotaFileIO;
class PepperFileIOHost : public ppapi::host::ResourceHost,
public base::SupportsWeakPtr<PepperFileIOHost> {
@@ -45,6 +42,12 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) OVERRIDE;
+ // Direct access for PepperFileSystemBrowserHost.
+ int64_t max_written_offset() const { return max_written_offset_; }
+ void set_max_written_offset(int64_t max_written_offset) {
+ max_written_offset_ = max_written_offset;
+ }
+
struct UIThreadStuff {
UIThreadStuff();
~UIThreadStuff();
@@ -76,31 +79,50 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
// PP_Error code and send back the reply. Note that the argument
// ReplyMessageContext is copied so that we have a closure containing all
// necessary information to reply.
- void ExecutePlatformGeneralCallback(ReplyMessageContext reply_context,
- base::PlatformFileError error_code);
- void ExecutePlatformOpenFileCallback(ReplyMessageContext reply_context,
- base::PlatformFileError error_code,
- base::PassPlatformFile file,
- bool unused_created);
- void ExecutePlatformWriteCallback(ReplyMessageContext reply_context,
- base::PlatformFileError error_code,
- int bytes_written);
+ void ExecutePlatformGeneralCallback(
+ ppapi::host::ReplyMessageContext reply_context,
+ base::PlatformFileError error_code);
+ void ExecutePlatformOpenFileCallback(
+ ppapi::host::ReplyMessageContext reply_context,
+ base::PlatformFileError error_code,
+ base::PassPlatformFile file,
+ bool unused_created);
+ void ExecutePlatformWriteCallback(
+ ppapi::host::ReplyMessageContext reply_context,
+ base::PlatformFileError error_code,
+ int bytes_written);
void GotUIThreadStuffForInternalFileSystems(
- ReplyMessageContext reply_context,
+ ppapi::host::ReplyMessageContext reply_context,
int platform_file_flags,
UIThreadStuff ui_thread_stuff);
void DidOpenInternalFile(
- ReplyMessageContext reply_context,
+ ppapi::host::ReplyMessageContext reply_context,
base::PlatformFileError result,
base::PlatformFile file,
const base::Closure& on_close_callback);
void GotResolvedRenderProcessId(
- ReplyMessageContext reply_context,
+ ppapi::host::ReplyMessageContext reply_context,
base::FilePath path,
int platform_file_flags,
base::ProcessId resolved_render_process_id);
+ void DidOpenQuotaFile(ppapi::host::ReplyMessageContext reply_context,
+ base::PlatformFile file,
+ int64_t max_written_offset);
+ void GotWriteQuota(ppapi::host::ReplyMessageContext reply_context,
+ int64_t offset,
+ const std::string& buffer,
+ int32_t granted);
+ void GotSetLengthQuota(ppapi::host::ReplyMessageContext reply_context,
+ int64_t length,
+ int32_t granted);
+ bool CallWrite(ppapi::host::ReplyMessageContext reply_context,
+ int64_t offset,
+ const std::string& buffer);
+ bool CallSetLength(ppapi::host::ReplyMessageContext reply_context,
+ int64_t length);
+
void DidCloseFile(base::PlatformFileError error);
// Adds file_ to |reply_context| with the specified |open_flags|.
@@ -115,6 +137,7 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
base::ProcessId resolved_render_process_id_;
base::PlatformFile file_;
+ int32_t open_flags_;
// The file system type specified in the Open() call. This will be
// PP_FILESYSTEMTYPE_INVALID before open was called. This value does not
@@ -122,19 +145,15 @@ class PepperFileIOHost : public ppapi::host::ResourceHost,
PP_FileSystemType file_system_type_;
base::WeakPtr<PepperFileSystemBrowserHost> file_system_host_;
+ // Used to check if we can pass file handle to plugins.
+ quota::QuotaLimitType quota_policy_;
+
// Valid only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}.
scoped_refptr<fileapi::FileSystemContext> file_system_context_;
fileapi::FileSystemURL file_system_url_;
base::Closure on_close_callback_;
-
- // Used to check if we can pass file handle to plugins.
- quota::QuotaLimitType quota_policy_;
-
- // Pointer to a QuotaFileIO instance, which is valid only while a file
- // of type PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY} is opened.
- scoped_ptr<QuotaFileIO> quota_file_io_;
-
- int32_t open_flags_;
+ int64_t max_written_offset_;
+ bool check_quota_;
ppapi::FileIOStateManager state_manager_;
diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
index a5064a69e4..94b3263a62 100644
--- a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
@@ -6,6 +6,8 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
+#include "content/browser/renderer_host/pepper/quota_reservation.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
@@ -19,7 +21,6 @@
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/file_system_util.h"
#include "ppapi/shared_impl/file_type_conversion.h"
-#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/fileapi/isolated_context.h"
#include "webkit/common/fileapi/file_system_util.h"
@@ -28,6 +29,9 @@ namespace content {
namespace {
+// This is the minimum amount of quota we reserve per file system.
+const int64_t kMinimumQuotaReservationSize = 1024 * 1024; // 1 MB
+
scoped_refptr<fileapi::FileSystemContext>
GetFileSystemContextFromRenderId(int render_process_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -42,6 +46,16 @@ GetFileSystemContextFromRenderId(int render_process_id) {
} // namespace
+PepperFileSystemBrowserHost::QuotaRequest::QuotaRequest(
+ int32_t amount_arg,
+ const RequestQuotaCallback& callback_arg)
+ : amount(amount_arg),
+ callback(callback_arg) {
+}
+
+PepperFileSystemBrowserHost::QuotaRequest::~QuotaRequest() {
+}
+
PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
PP_Instance instance,
PP_Resource resource,
@@ -52,6 +66,8 @@ PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
called_open_(false),
opened_(false),
file_system_context_(NULL),
+ reserved_quota_(0),
+ reserving_quota_(false),
weak_factory_(this) {
}
@@ -78,7 +94,7 @@ void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url,
BrowserThread::UI,
FROM_HERE,
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
- base::Bind(&PepperFileSystemBrowserHost::OpenExistingWithContext,
+ base::Bind(&PepperFileSystemBrowserHost::OpenExistingFileSystem,
weak_factory_.GetWeakPtr(), callback));
}
@@ -100,6 +116,67 @@ bool PepperFileSystemBrowserHost::IsFileSystemHost() {
return true;
}
+void PepperFileSystemBrowserHost::OpenQuotaFile(
+ PepperFileIOHost* file_io_host,
+ const base::FilePath& file_path,
+ const OpenQuotaFileCallback& callback) {
+ int32_t id = file_io_host->pp_resource();
+ std::pair<FileMap::iterator, bool> insert_result =
+ files_.insert(std::make_pair(id, file_io_host));
+ if (insert_result.second) {
+ base::PostTaskAndReplyWithResult(
+ file_system_context_->default_file_task_runner(),
+ FROM_HERE,
+ base::Bind(&QuotaReservation::OpenFile,
+ quota_reservation_,
+ id,
+ file_path),
+ callback);
+ } else {
+ NOTREACHED();
+ }
+}
+
+void PepperFileSystemBrowserHost::CloseQuotaFile(
+ PepperFileIOHost* file_io_host) {
+ int32_t id = file_io_host->pp_resource();
+ int64_t max_written_offset = 0;
+ FileMap::iterator it = files_.find(id);
+ if (it != files_.end()) {
+ max_written_offset = file_io_host->max_written_offset();
+ files_.erase(it);
+ } else {
+ NOTREACHED();
+ return;
+ }
+
+ file_system_context_->default_file_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&QuotaReservation::CloseFile,
+ quota_reservation_,
+ id,
+ max_written_offset));
+}
+
+int32_t PepperFileSystemBrowserHost::RequestQuota(
+ int32_t amount,
+ const RequestQuotaCallback& callback) {
+ DCHECK(amount >= 0);
+ if (!reserving_quota_ && reserved_quota_ >= amount) {
+ reserved_quota_ -= amount;
+ return amount;
+ }
+
+ // Queue up a pending quota request.
+ pending_quota_requests_.push(QuotaRequest(amount, callback));
+
+ // Reserve more quota if we haven't already.
+ if (!reserving_quota_)
+ ReserveQuota(amount);
+
+ return PP_OK_COMPLETIONPENDING;
+}
+
int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
ppapi::host::HostMessageContext* context,
int64_t /* unused */) {
@@ -128,14 +205,14 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
BrowserThread::UI,
FROM_HERE,
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
- base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext,
+ base::Bind(&PepperFileSystemBrowserHost::OpenFileSystem,
weak_factory_.GetWeakPtr(),
context->MakeReplyMessageContext(),
file_system_type));
return PP_OK_COMPLETIONPENDING;
}
-void PepperFileSystemBrowserHost::OpenExistingWithContext(
+void PepperFileSystemBrowserHost::OpenExistingFileSystem(
const base::Closure& callback,
scoped_refptr<fileapi::FileSystemContext> file_system_context) {
if (file_system_context.get()) {
@@ -147,10 +224,15 @@ void PepperFileSystemBrowserHost::OpenExistingWithContext(
LOG(WARNING) << "Could not retrieve file system context.";
}
SetFileSystemContext(file_system_context);
+
+ int32_t pp_error = CreateQuotaReservation(callback);
+ if (pp_error == PP_OK_COMPLETIONPENDING)
+ return;
+
callback.Run();
}
-void PepperFileSystemBrowserHost::GotFileSystemContext(
+void PepperFileSystemBrowserHost::OpenFileSystem(
ppapi::host::ReplyMessageContext reply_context,
fileapi::FileSystemType file_system_type,
scoped_refptr<fileapi::FileSystemContext> file_system_context) {
@@ -159,13 +241,16 @@ void PepperFileSystemBrowserHost::GotFileSystemContext(
reply_context, GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED);
return;
}
+
+ SetFileSystemContext(file_system_context);
+
GURL origin = browser_ppapi_host_->GetDocumentURLForInstance(
pp_instance()).GetOrigin();
- file_system_context->OpenFileSystem(origin, file_system_type,
+ file_system_context_->OpenFileSystem(origin, file_system_type,
fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete,
- weak_factory_.GetWeakPtr(), reply_context));
- SetFileSystemContext(file_system_context);
+ weak_factory_.GetWeakPtr(),
+ reply_context));
}
void PepperFileSystemBrowserHost::OpenFileSystemComplete(
@@ -177,12 +262,20 @@ void PepperFileSystemBrowserHost::OpenFileSystemComplete(
if (pp_error == PP_OK) {
opened_ = true;
root_url_ = root;
+
+ pp_error = CreateQuotaReservation(
+ base::Bind(&PepperFileSystemBrowserHost::SendReplyForFileSystem,
+ weak_factory_.GetWeakPtr(),
+ reply_context,
+ static_cast<int32_t>(PP_OK)));
+ if (pp_error == PP_OK_COMPLETIONPENDING)
+ return;
+ // For PP_OK and all other error codes, we can send the reply now.
}
- reply_context.params.set_result(pp_error);
- host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply());
+ SendReplyForFileSystem(reply_context, pp_error);
}
-void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext(
+void PepperFileSystemBrowserHost::OpenIsolatedFileSystem(
ppapi::host::ReplyMessageContext reply_context,
const std::string& fsid,
PP_IsolatedFileSystemType_Private type,
@@ -273,16 +366,27 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem(
return PP_ERROR_FAILED;
}
+ root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString(
+ browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(),
+ fsid, ppapi::IsolatedFileSystemTypeToRootName(type)));
+
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::UI,
FROM_HERE,
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
- base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext,
+ base::Bind(&PepperFileSystemBrowserHost::OpenIsolatedFileSystem,
weak_factory_.GetWeakPtr(),
context->MakeReplyMessageContext(), fsid, type));
return PP_OK_COMPLETIONPENDING;
}
+void PepperFileSystemBrowserHost::SendReplyForFileSystem(
+ ppapi::host::ReplyMessageContext reply_context,
+ int32_t pp_error) {
+ reply_context.params.set_result(pp_error);
+ host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply());
+}
+
void PepperFileSystemBrowserHost::SendReplyForIsolatedFileSystem(
ppapi::host::ReplyMessageContext reply_context,
const std::string& fsid,
@@ -303,6 +407,95 @@ void PepperFileSystemBrowserHost::SetFileSystemContext(
}
}
+int32_t PepperFileSystemBrowserHost::CreateQuotaReservation(
+ const base::Closure& callback) {
+ if (!ppapi::FileSystemTypeHasQuota(type_))
+ return PP_OK;
+
+ DCHECK(root_url_.is_valid());
+ base::PostTaskAndReplyWithResult(
+ file_system_context_->default_file_task_runner(),
+ FROM_HERE,
+ base::Bind(&QuotaReservation::Create,
+ file_system_context_,
+ root_url_.GetOrigin(),
+ ppapi::PepperFileSystemTypeToFileSystemType(type_)),
+ base::Bind(&PepperFileSystemBrowserHost::GotQuotaReservation,
+ weak_factory_.GetWeakPtr(),
+ callback));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+void PepperFileSystemBrowserHost::GotQuotaReservation(
+ const base::Closure& callback,
+ scoped_refptr<QuotaReservation> quota_reservation) {
+ quota_reservation_ = quota_reservation;
+ callback.Run();
+}
+
+void PepperFileSystemBrowserHost::ReserveQuota(int32_t amount) {
+ DCHECK(!reserving_quota_);
+ reserving_quota_ = true;
+
+ // Get the max_written_offset for each open file.
+ QuotaReservation::OffsetMap max_written_offsets;
+ for (FileMap::iterator it = files_.begin(); it != files_.end(); ++ it) {
+ max_written_offsets.insert(
+ std::make_pair(it->first, it->second->max_written_offset()));
+ }
+
+ int64_t reservation_amount = std::max<int64_t>(kMinimumQuotaReservationSize,
+ amount);
+ file_system_context_->default_file_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&QuotaReservation::ReserveQuota,
+ quota_reservation_,
+ reservation_amount,
+ max_written_offsets,
+ base::Bind(&PepperFileSystemBrowserHost::GotReservedQuota,
+ weak_factory_.GetWeakPtr())));
+}
+
+void PepperFileSystemBrowserHost::GotReservedQuota(
+ int64_t amount,
+ const QuotaReservation::OffsetMap& max_written_offsets) {
+ DCHECK(reserving_quota_);
+ reserving_quota_ = false;
+ reserved_quota_ = amount;
+
+ // Update open files with their new base sizes. This won't write over any
+ // updates since the files are waiting for quota and can't write.
+ for (FileMap::iterator it = files_.begin(); it != files_.end(); ++ it) {
+ QuotaReservation::OffsetMap::const_iterator offset_it =
+ max_written_offsets.find(it->first);
+ if (offset_it != max_written_offsets.end())
+ it->second->set_max_written_offset(offset_it->second);
+ else
+ NOTREACHED();
+ }
+
+ DCHECK(!pending_quota_requests_.empty());
+ // If we can't grant the first request after refreshing reserved_quota_, then
+ // fail all pending quota requests to avoid an infinite refresh/fail loop.
+ bool fail_all = reserved_quota_ < pending_quota_requests_.front().amount;
+ while (!pending_quota_requests_.empty()) {
+ QuotaRequest& request = pending_quota_requests_.front();
+ if (fail_all) {
+ request.callback.Run(0);
+ pending_quota_requests_.pop();
+ } else if (reserved_quota_ >= request.amount) {
+ reserved_quota_ -= request.amount;
+ request.callback.Run(request.amount);
+ pending_quota_requests_.pop();
+ } else {
+ // Refresh the quota reservation for the first pending request that we
+ // can't satisfy.
+ ReserveQuota(request.amount);
+ break;
+ }
+ }
+}
+
std::string PepperFileSystemBrowserHost::GetPluginMimeType() const {
base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath();
PepperPluginInfo* info =
diff --git a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
index e872bc5b49..5dcf333eb5 100644
--- a/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
+++ b/content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
@@ -5,11 +5,14 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_
+#include <queue>
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/renderer_host/pepper/quota_reservation.h"
#include "content/common/content_export.h"
#include "ppapi/c/pp_file_info.h"
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
@@ -17,11 +20,11 @@
#include "ppapi/host/resource_host.h"
#include "url/gurl.h"
#include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/common/fileapi/file_system_types.h"
namespace content {
class BrowserPpapiHost;
+class PepperFileIOHost;
class CONTENT_EXPORT PepperFileSystemBrowserHost
: public ppapi::host::ResourceHost,
@@ -41,7 +44,7 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
// Calls |callback| when complete.
void OpenExisting(const GURL& root_url, const base::Closure& callback);
- // ppapi::host::ResourceHost override.
+ // ppapi::host::ResourceHost overrides.
virtual int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) OVERRIDE;
@@ -60,14 +63,39 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
fileapi::FileSystemOperationRunner* GetFileSystemOperationRunner() const {
return file_system_operation_runner_.get();
}
-
+ bool ChecksQuota() const { return quota_reservation_ != NULL; }
+ // Opens a file for writing with quota checks. Returns the file size in the
+ // callback.
+ typedef base::Callback<void(int64_t)> OpenQuotaFileCallback;
+ void OpenQuotaFile(PepperFileIOHost* file_io_host,
+ const base::FilePath& file_path,
+ const OpenQuotaFileCallback& callback);
+ // Closes the file. This must be called after OpenQuotaFile and before the
+ // PepperFileIOHost is destroyed.
+ void CloseQuotaFile(PepperFileIOHost* file_io_host);
+ // Requests the given amount of quota. Returns the amount requested or
+ // PP_OK_COMPLETIONPENDING, in which case the amount granted is returned in
+ // the callback. Requests can't partially succeed so the amount granted is
+ // either 0 or the amount of the request. Requesting an amount of 0 will
+ // return immediately with a 0 result.
+ typedef base::Callback<void(int32_t)> RequestQuotaCallback;
+ int32_t RequestQuota(int32_t amount,
+ const RequestQuotaCallback& callback);
private:
friend class PepperFileSystemBrowserHostTest;
- void OpenExistingWithContext(
+ struct QuotaRequest {
+ QuotaRequest(int32_t amount, const RequestQuotaCallback& callback);
+ ~QuotaRequest();
+
+ int32_t amount;
+ RequestQuotaCallback callback;
+ };
+
+ void OpenExistingFileSystem(
const base::Closure& callback,
scoped_refptr<fileapi::FileSystemContext> file_system_context);
- void GotFileSystemContext(
+ void OpenFileSystem(
ppapi::host::ReplyMessageContext reply_context,
fileapi::FileSystemType file_system_type,
scoped_refptr<fileapi::FileSystemContext> file_system_context);
@@ -76,7 +104,7 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
const GURL& root,
const std::string& name,
base::PlatformFileError error);
- void GotIsolatedFileSystemContext(
+ void OpenIsolatedFileSystem(
ppapi::host::ReplyMessageContext reply_context,
const std::string& fsid,
PP_IsolatedFileSystemType_Private type,
@@ -97,6 +125,9 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
const std::string& fsid,
PP_IsolatedFileSystemType_Private type);
+ void SendReplyForFileSystem(
+ ppapi::host::ReplyMessageContext reply_context,
+ int32_t pp_error);
void SendReplyForIsolatedFileSystem(
ppapi::host::ReplyMessageContext reply_context,
const std::string& fsid,
@@ -105,6 +136,15 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
void SetFileSystemContext(
scoped_refptr<fileapi::FileSystemContext> file_system_context);
+ int32_t CreateQuotaReservation(const base::Closure& callback);
+ void GotQuotaReservation(
+ const base::Closure& callback,
+ scoped_refptr<QuotaReservation> quota_reservation);
+
+ void ReserveQuota(int32_t amount);
+ void GotReservedQuota(int64_t amount,
+ const QuotaReservation::OffsetMap& max_written_offsets);
+
std::string GetPluginMimeType() const;
// Returns plugin ID generated from plugin's MIME type.
@@ -114,12 +154,24 @@ class CONTENT_EXPORT PepperFileSystemBrowserHost
PP_FileSystemType type_;
bool called_open_; // whether open has been called.
- bool opened_; // whether open has succeeded.
+ bool opened_; // whether open succeeded.
GURL root_url_;
scoped_refptr<fileapi::FileSystemContext> file_system_context_;
scoped_ptr<fileapi::FileSystemOperationRunner> file_system_operation_runner_;
+ // Used only for file systems with quota.
+ // When a PepperFileIOHost calls OpenQuotaFile, we add the id and a non-owning
+ // pointer to this map. CloseQuotaFile must be called when before the host is
+ // destroyed.
+ typedef std::map<int32_t, PepperFileIOHost*> FileMap;
+ FileMap files_;
+ std::queue<QuotaRequest> pending_quota_requests_;
+ int64_t reserved_quota_;
+ bool reserving_quota_;
+ // Access only on the FileSystemContext's default_file_task_runner().
+ scoped_refptr<QuotaReservation> quota_reservation_;
+
std::string fsid_; // used only for isolated filesystems.
base::WeakPtrFactory<PepperFileSystemBrowserHost> weak_factory_;
diff --git a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
index 7e010d6dbb..ba8a8b9136 100644
--- a/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
@@ -194,7 +194,7 @@ int32_t PepperFlashFileMessageFilter::OnCreateDir(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
}
- bool result = file_util::CreateDirectory(full_path);
+ bool result = base::CreateDirectory(full_path);
return ppapi::PlatformFileErrorToPepperError(result ?
base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
}
@@ -210,7 +210,7 @@ int32_t PepperFlashFileMessageFilter::OnQueryFile(
}
base::PlatformFileInfo info;
- bool result = file_util::GetFileInfo(full_path, &info);
+ bool result = base::GetFileInfo(full_path, &info);
context->reply_msg = PpapiPluginMsg_FlashFile_QueryFileReply(info);
return ppapi::PlatformFileErrorToPepperError(result ?
base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
@@ -253,13 +253,13 @@ int32_t PepperFlashFileMessageFilter::OnCreateTemporaryFile(
dir_path, base::Bind(&CanCreateReadWrite));
if (validated_dir_path.empty() ||
(!base::DirectoryExists(validated_dir_path) &&
- !file_util::CreateDirectory(validated_dir_path))) {
+ !base::CreateDirectory(validated_dir_path))) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_ACCESS_DENIED);
}
base::FilePath file_path;
- if (!file_util::CreateTemporaryFileInDir(validated_dir_path, &file_path)) {
+ if (!base::CreateTemporaryFileInDir(validated_dir_path, &file_path)) {
return ppapi::PlatformFileErrorToPepperError(
base::PLATFORM_FILE_ERROR_FAILED);
}
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
index e5cdcc6b01..3530e1e1b5 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_win.cc
@@ -73,7 +73,7 @@ void GetFontsInFamily_SlowBlocking(const std::string& family,
LOGFONTW logfont;
memset(&logfont, 0, sizeof(logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
- string16 family16 = UTF8ToUTF16(family);
+ base::string16 family16 = UTF8ToUTF16(family);
memcpy(&logfont.lfFaceName, &family16[0], sizeof(logfont.lfFaceName));
base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
::EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROCW)&EnumFontsInFamilyProc,
diff --git a/content/browser/renderer_host/pepper/quota_file_io.cc b/content/browser/renderer_host/pepper/quota_file_io.cc
deleted file mode 100644
index 0768574200..0000000000
--- a/content/browser/renderer_host/pepper/quota_file_io.cc
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/pepper/quota_file_io.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/stl_util.h"
-#include "base/task_runner_util.h"
-
-using base::PlatformFile;
-using base::PlatformFileError;
-using quota::StorageType;
-
-namespace content {
-
-namespace {
-StorageType PPFileSystemTypeToQuotaStorageType(PP_FileSystemType type) {
- switch (type) {
- case PP_FILESYSTEMTYPE_LOCALPERSISTENT:
- return quota::kStorageTypePersistent;
- case PP_FILESYSTEMTYPE_LOCALTEMPORARY:
- return quota::kStorageTypeTemporary;
- default:
- return quota::kStorageTypeUnknown;
- }
- NOTREACHED();
- return quota::kStorageTypeUnknown;
-}
-
-int WriteAdapter(PlatformFile file, int64 offset,
- scoped_ptr<char[]> data, int size) {
- return base::WritePlatformFile(file, offset, data.get(), size);
-}
-
-} // namespace
-
-class QuotaFileIO::PendingOperationBase {
- public:
- virtual ~PendingOperationBase() {}
-
- // Either one of Run() or DidFail() is called (the latter is called when
- // there was more than one error during quota queries).
- virtual void Run() = 0;
- virtual void DidFail(PlatformFileError error) = 0;
-
- protected:
- explicit PendingOperationBase(QuotaFileIO* quota_io) : quota_io_(quota_io) {
- DCHECK(quota_io_);
- quota_io_->WillUpdate();
- }
-
- QuotaFileIO* quota_io_;
-};
-
-class QuotaFileIO::WriteOperation : public PendingOperationBase {
- public:
- WriteOperation(QuotaFileIO* quota_io,
- int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- const WriteCallback& callback)
- : PendingOperationBase(quota_io),
- offset_(offset),
- bytes_to_write_(bytes_to_write),
- callback_(callback),
- finished_(false),
- status_(base::PLATFORM_FILE_OK),
- bytes_written_(0),
- weak_factory_(this) {
- // TODO(kinuko): Check the API convention if we really need to keep a copy
- // of the buffer during the async write operations.
- buffer_.reset(new char[bytes_to_write]);
- memcpy(buffer_.get(), buffer, bytes_to_write);
- }
- virtual ~WriteOperation() {}
- virtual void Run() OVERRIDE {
- DCHECK(quota_io_);
- if (quota_io_->CheckIfExceedsQuota(offset_ + bytes_to_write_)) {
- DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE);
- return;
- }
- DCHECK(buffer_.get());
-
- if (!base::PostTaskAndReplyWithResult(
- quota_io_->delegate()->GetFileThreadMessageLoopProxy().get(),
- FROM_HERE,
- base::Bind(&WriteAdapter,
- quota_io_->file_,
- offset_,
- base::Passed(&buffer_),
- bytes_to_write_),
- base::Bind(&WriteOperation::DidWrite,
- weak_factory_.GetWeakPtr()))) {
- DidFail(base::PLATFORM_FILE_ERROR_FAILED);
- return;
- }
- }
-
- virtual void DidFail(PlatformFileError error) OVERRIDE {
- DidFinish(error, 0);
- }
-
- bool finished() const { return finished_; }
-
- virtual void WillRunCallback() {
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(&WriteOperation::RunCallback, weak_factory_.GetWeakPtr()));
- }
-
- private:
- void DidWrite(int bytes_written) {
- base::PlatformFileError error = bytes_written > 0 ?
- base::PLATFORM_FILE_OK : base::PLATFORM_FILE_ERROR_FAILED;
- DidFinish(error, bytes_written);
- }
-
- void DidFinish(PlatformFileError status, int bytes_written) {
- finished_ = true;
- status_ = status;
- bytes_written_ = bytes_written;
- int64_t max_offset =
- (status != base::PLATFORM_FILE_OK) ? 0 : offset_ + bytes_written;
- // This may delete itself by calling RunCallback.
- quota_io_->DidWrite(this, max_offset);
- }
-
- virtual void RunCallback() {
- DCHECK_EQ(false, callback_.is_null());
- callback_.Run(status_, bytes_written_);
- delete this;
- }
-
- const int64_t offset_;
- scoped_ptr<char[]> buffer_;
- const int32_t bytes_to_write_;
- WriteCallback callback_;
- bool finished_;
- PlatformFileError status_;
- int64_t bytes_written_;
- base::WeakPtrFactory<WriteOperation> weak_factory_;
-};
-
-class QuotaFileIO::SetLengthOperation : public PendingOperationBase {
- public:
- SetLengthOperation(QuotaFileIO* quota_io,
- int64_t length,
- const StatusCallback& callback)
- : PendingOperationBase(quota_io),
- length_(length),
- callback_(callback),
- weak_factory_(this) {}
-
- virtual ~SetLengthOperation() {}
-
- virtual void Run() OVERRIDE {
- DCHECK(quota_io_);
- if (quota_io_->CheckIfExceedsQuota(length_)) {
- DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE);
- return;
- }
-
- if (!base::FileUtilProxy::Truncate(
- quota_io_->delegate()->GetFileThreadMessageLoopProxy().get(),
- quota_io_->file_,
- length_,
- base::Bind(&SetLengthOperation::DidFinish,
- weak_factory_.GetWeakPtr()))) {
- DidFail(base::PLATFORM_FILE_ERROR_FAILED);
- return;
- }
- }
-
- virtual void DidFail(PlatformFileError error) OVERRIDE {
- DidFinish(error);
- }
-
- private:
- void DidFinish(PlatformFileError status) {
- quota_io_->DidSetLength(status, length_);
- DCHECK_EQ(false, callback_.is_null());
- callback_.Run(status);
- delete this;
- }
-
- int64_t length_;
- StatusCallback callback_;
- base::WeakPtrFactory<SetLengthOperation> weak_factory_;
-};
-
-// QuotaFileIO --------------------------------------------------------------
-
-QuotaFileIO::QuotaFileIO(
- Delegate* delegate,
- PlatformFile file,
- const GURL& file_url,
- PP_FileSystemType type)
- : delegate_(delegate),
- file_(file),
- file_url_(file_url),
- storage_type_(PPFileSystemTypeToQuotaStorageType(type)),
- cached_file_size_(0),
- cached_available_space_(0),
- outstanding_quota_queries_(0),
- outstanding_errors_(0),
- max_written_offset_(0),
- inflight_operations_(0),
- weak_factory_(this) {
- DCHECK_NE(base::kInvalidPlatformFileValue, file_);
- DCHECK_NE(quota::kStorageTypeUnknown, storage_type_);
-}
-
-QuotaFileIO::~QuotaFileIO() {
- // Note that this doesn't dispatch pending callbacks.
- STLDeleteContainerPointers(pending_operations_.begin(),
- pending_operations_.end());
- STLDeleteContainerPointers(pending_callbacks_.begin(),
- pending_callbacks_.end());
-}
-
-bool QuotaFileIO::Write(
- int64_t offset, const char* buffer, int32_t bytes_to_write,
- const WriteCallback& callback) {
- if (bytes_to_write <= 0)
- return false;
-
- WriteOperation* op = new WriteOperation(
- this, offset, buffer, bytes_to_write, callback);
- return RegisterOperationForQuotaChecks(op);
-}
-
-bool QuotaFileIO::SetLength(int64_t length, const StatusCallback& callback) {
- DCHECK(pending_operations_.empty());
- SetLengthOperation* op = new SetLengthOperation(this, length, callback);
- return RegisterOperationForQuotaChecks(op);
-}
-
-bool QuotaFileIO::RegisterOperationForQuotaChecks(
- PendingOperationBase* op_ptr) {
- scoped_ptr<PendingOperationBase> op(op_ptr);
- if (pending_operations_.empty()) {
- // This is the first pending quota check. Run querying the file size
- // and available space.
- outstanding_quota_queries_ = 0;
- outstanding_errors_ = 0;
-
- // Query the file size.
- ++outstanding_quota_queries_;
- if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
- delegate_->GetFileThreadMessageLoopProxy().get(),
- file_,
- base::Bind(&QuotaFileIO::DidQueryInfoForQuota,
- weak_factory_.GetWeakPtr()))) {
- // This makes the call fail synchronously; we do not fire the callback
- // here but just delete the operation and return false.
- return false;
- }
-
- // Query the current available space.
- ++outstanding_quota_queries_;
- delegate_->QueryAvailableSpace(
- file_url_.GetOrigin(), storage_type_,
- base::Bind(&QuotaFileIO::DidQueryAvailableSpace,
- weak_factory_.GetWeakPtr()));
- }
- pending_operations_.push_back(op.release());
- return true;
-}
-
-void QuotaFileIO::DidQueryInfoForQuota(
- base::PlatformFileError error_code,
- const base::PlatformFileInfo& file_info) {
- if (error_code != base::PLATFORM_FILE_OK)
- ++outstanding_errors_;
- cached_file_size_ = file_info.size;
- DCHECK_GT(outstanding_quota_queries_, 0);
- if (--outstanding_quota_queries_ == 0)
- DidQueryForQuotaCheck();
-}
-
-void QuotaFileIO::DidQueryAvailableSpace(int64_t avail_space) {
- cached_available_space_ = avail_space;
- DCHECK_GT(outstanding_quota_queries_, 0);
- if (--outstanding_quota_queries_ == 0)
- DidQueryForQuotaCheck();
-}
-
-void QuotaFileIO::DidQueryForQuotaCheck() {
- DCHECK(!pending_operations_.empty());
- DCHECK_GT(inflight_operations_, 0);
- while (!pending_operations_.empty()) {
- PendingOperationBase* op = pending_operations_.front();
- pending_operations_.pop_front();
- pending_callbacks_.push_back(op);
- if (outstanding_errors_ > 0) {
- op->DidFail(base::PLATFORM_FILE_ERROR_FAILED);
- continue;
- }
- op->Run();
- }
-}
-
-bool QuotaFileIO::CheckIfExceedsQuota(int64_t new_file_size) const {
- DCHECK_GE(cached_file_size_, 0);
- DCHECK_GE(cached_available_space_, 0);
- return new_file_size - cached_file_size_ > cached_available_space_;
-}
-
-void QuotaFileIO::WillUpdate() {
- if (inflight_operations_++ == 0) {
- delegate_->WillUpdateFile(file_url_);
- DCHECK_EQ(0, max_written_offset_);
- }
-}
-
-void QuotaFileIO::DidWrite(WriteOperation* op,
- int64_t written_offset_end) {
- max_written_offset_ = std::max(max_written_offset_, written_offset_end);
- DCHECK_GT(inflight_operations_, 0);
- DCHECK(!pending_callbacks_.empty());
- // Fire callbacks for finished operations.
- while (!pending_callbacks_.empty()) {
- WriteOperation* op = static_cast<WriteOperation*>(
- pending_callbacks_.front());
- if (!op->finished())
- break;
- pending_callbacks_.pop_front();
- op->WillRunCallback();
- }
- // If we have no more pending writes, notify the browser that we did
- // update the file.
- if (--inflight_operations_ == 0) {
- DCHECK(pending_operations_.empty());
- int64_t growth = max_written_offset_ - cached_file_size_;
- growth = growth < 0 ? 0 : growth;
-
- delegate_->DidUpdateFile(file_url_, growth);
- max_written_offset_ = 0;
- }
-}
-
-void QuotaFileIO::DidSetLength(PlatformFileError error, int64_t new_file_size) {
- DCHECK_EQ(1, inflight_operations_);
- pending_callbacks_.pop_front();
- DCHECK(pending_callbacks_.empty());
- int64_t delta = (error != base::PLATFORM_FILE_OK) ? 0 :
- new_file_size - cached_file_size_;
-
- delegate_->DidUpdateFile(file_url_, delta);
- inflight_operations_ = 0;
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/pepper/quota_file_io.h b/content/browser/renderer_host/pepper/quota_file_io.h
deleted file mode 100644
index 54229b87a4..0000000000
--- a/content/browser/renderer_host/pepper/quota_file_io.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_FILE_IO_H_
-#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_FILE_IO_H_
-
-#include <deque>
-
-#include "base/callback_forward.h"
-#include "base/files/file_util_proxy.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/platform_file.h"
-#include "content/common/content_export.h"
-#include "ppapi/c/pp_file_info.h"
-#include "url/gurl.h"
-#include "webkit/common/quota/quota_types.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace content {
-
-// This class is created per PPB_FileIO_Impl instance and provides
-// write operations for quota-managed files (i.e. files of
-// PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}).
-class QuotaFileIO {
- public:
- // For quota handlings for FileIO API. This will be owned by QuotaFileIO.
- class Delegate {
- public:
- virtual ~Delegate() {}
- typedef base::Callback<void (int64)> AvailableSpaceCallback;
- virtual void QueryAvailableSpace(
- const GURL& origin,
- quota::StorageType type,
- const AvailableSpaceCallback& callback) = 0;
- virtual void WillUpdateFile(const GURL& file_path) = 0;
- virtual void DidUpdateFile(const GURL& file_path, int64_t delta) = 0;
- // Returns a MessageLoopProxy instance associated with the message loop of
- // the file thread.
- virtual scoped_refptr<base::MessageLoopProxy>
- GetFileThreadMessageLoopProxy() = 0;
- };
-
- typedef base::FileUtilProxy::WriteCallback WriteCallback;
- typedef base::FileUtilProxy::StatusCallback StatusCallback;
-
- CONTENT_EXPORT QuotaFileIO(Delegate* delegate,
- base::PlatformFile file,
- const GURL& path_url,
- PP_FileSystemType type);
- CONTENT_EXPORT ~QuotaFileIO();
-
- // Performs write or setlength operation with quota checks.
- // Returns true when the operation is successfully dispatched.
- // |bytes_to_write| must be geater than zero.
- // |callback| will be dispatched when the operation completes.
- // Otherwise it returns false and |callback| will not be dispatched.
- // |callback| will not be dispatched either when this instance is
- // destroyed before the operation completes.
- // SetLength cannot be called while there're any in-flight
- // operations. For Write it is guaranteed that |callback| are
- // always dispatched in the same order as Write being called.
- CONTENT_EXPORT bool Write(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- const WriteCallback& callback);
- CONTENT_EXPORT bool SetLength(int64_t length,
- const StatusCallback& callback);
-
- Delegate* delegate() const { return delegate_.get(); }
-
- private:
- class PendingOperationBase;
- class WriteOperation;
- class SetLengthOperation;
-
- bool CheckIfExceedsQuota(int64_t new_file_size) const;
- void WillUpdate();
- void DidWrite(WriteOperation* op, int64_t written_offset_end);
- void DidSetLength(base::PlatformFileError error, int64_t new_file_size);
-
- bool RegisterOperationForQuotaChecks(PendingOperationBase* op);
- void DidQueryInfoForQuota(base::PlatformFileError error_code,
- const base::PlatformFileInfo& file_info);
- void DidQueryAvailableSpace(int64_t avail_space);
- void DidQueryForQuotaCheck();
-
- scoped_ptr<Delegate> delegate_;
-
- // The file information associated to this instance.
- base::PlatformFile file_;
- GURL file_url_;
- quota::StorageType storage_type_;
-
- // Pending operations that are waiting quota checks and pending
- // callbacks that are to be fired after the operation;
- // we use two separate queues for them so that we can safely dequeue the
- // pending callbacks while enqueueing new operations. (This could
- // happen when callbacks are dispatched synchronously due to error etc.)
- std::deque<PendingOperationBase*> pending_operations_;
- std::deque<PendingOperationBase*> pending_callbacks_;
-
- // Valid only while there're pending quota checks.
- int64_t cached_file_size_;
- int64_t cached_available_space_;
-
- // Quota-related queries and errors occurred during in-flight quota checks.
- int outstanding_quota_queries_;
- int outstanding_errors_;
-
- // For parallel writes bookkeeping.
- int64_t max_written_offset_;
- int inflight_operations_;
-
- base::WeakPtrFactory<QuotaFileIO> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(QuotaFileIO);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_FILE_IO_H_
diff --git a/content/browser/renderer_host/pepper/quota_file_io_unittest.cc b/content/browser/renderer_host/pepper/quota_file_io_unittest.cc
deleted file mode 100644
index bcc08d3434..0000000000
--- a/content/browser/renderer_host/pepper/quota_file_io_unittest.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <deque>
-#include <limits>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/platform_file.h"
-#include "content/browser/renderer_host/pepper/quota_file_io.h"
-#include "content/test/ppapi_unittest.h"
-
-using base::MessageLoopProxy;
-using base::PlatformFile;
-using base::PlatformFileError;
-
-namespace content {
-
-namespace {
-class QuotaMockDelegate : public QuotaFileIO::Delegate {
- public:
- typedef QuotaFileIO::Delegate::AvailableSpaceCallback Callback;
-
- QuotaMockDelegate()
- : available_space_(0),
- will_update_count_(0),
- file_thread_(MessageLoopProxy::current()),
- weak_factory_(this) {
- }
- virtual ~QuotaMockDelegate() {}
-
- virtual void QueryAvailableSpace(
- const GURL& origin,
- quota::StorageType type,
- const Callback& callback) OVERRIDE {
- DCHECK_EQ(false, callback.is_null());
- MessageLoopProxy::current()->PostTask(
- FROM_HERE, base::Bind(
- &QuotaMockDelegate::RunAvailableSpaceCallback,
- weak_factory_.GetWeakPtr(), callback));
- }
-
- virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
- file_path_ = file_path;
- ++will_update_count_;
- }
-
- virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
- ASSERT_EQ(file_path_, file_path);
- ASSERT_GT(will_update_count_, 0);
- --will_update_count_;
- available_space_ -= delta;
- }
-
- virtual scoped_refptr<base::MessageLoopProxy>
- GetFileThreadMessageLoopProxy() OVERRIDE {
- return file_thread_;
- }
-
- void set_available_space(int64 available) { available_space_ = available; }
- int64_t available_space() const { return available_space_; }
-
- private:
- void RunAvailableSpaceCallback(const Callback& callback) {
- callback.Run(available_space_);
- }
-
- int64_t available_space_;
- int will_update_count_;
- GURL file_path_;
- scoped_refptr<MessageLoopProxy> file_thread_;
- base::WeakPtrFactory<QuotaMockDelegate> weak_factory_;
-};
-} // namespace
-
-class QuotaFileIOTest : public PpapiUnittest {
- public:
- QuotaFileIOTest()
- : delegate_(NULL),
- weak_factory_(this) {}
-
- virtual void SetUp() OVERRIDE {
- PpapiUnittest::SetUp();
- ASSERT_TRUE(dir_.CreateUniqueTempDir());
- base::FilePath path;
- ASSERT_TRUE(file_util::CreateTemporaryFileInDir(dir_.path(), &path));
- int file_flags = base::PLATFORM_FILE_OPEN |
- base::PLATFORM_FILE_READ |
- base::PLATFORM_FILE_WRITE |
- base::PLATFORM_FILE_WRITE_ATTRIBUTES;
- bool created = false;
- file_ = base::kInvalidPlatformFileValue;
- PlatformFileError error = base::PLATFORM_FILE_OK;
- file_ = base::CreatePlatformFile(path, file_flags, &created, &error);
- ASSERT_EQ(base::PLATFORM_FILE_OK, error);
- ASSERT_NE(base::kInvalidPlatformFileValue, file_);
- ASSERT_FALSE(created);
- delegate_ = new QuotaMockDelegate; // Owned by QuotaFileIO.
- quota_file_io_.reset(new QuotaFileIO(
- delegate_, file_, GURL(), PP_FILESYSTEMTYPE_LOCALTEMPORARY));
- }
-
- virtual void TearDown() OVERRIDE {
- quota_file_io_.reset();
- if (file_ != base::kInvalidPlatformFileValue)
- base::ClosePlatformFile(file_);
- PpapiUnittest::TearDown();
- }
-
- protected:
- void WriteTestBody() {
- // Attempt to write zero bytes.
- EXPECT_FALSE(quota_file_io_->Write(
- 0, "data", 0,
- base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
- // Attempt to write negative number of bytes.
- EXPECT_FALSE(quota_file_io_->Write(
- 0, "data", std::numeric_limits<int32_t>::min(),
- base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
-
- delegate()->set_available_space(100);
- std::string read_buffer;
-
- // Write 8 bytes at offset 0 (-> length=8).
- std::string data("12345678");
- Write(0, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 8, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(8, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ(data, read_buffer);
-
- // Write 5 bytes at offset 5 (-> length=10).
- data = "55555";
- Write(5, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 10, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(10, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ("1234555555", read_buffer);
-
- // Write 7 bytes at offset 8 (-> length=15).
- data = "9012345";
- Write(8, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 15, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(15, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ("123455559012345", read_buffer);
-
- // Write 2 bytes at offset 2 (-> length=15).
- data = "33";
- Write(2, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 15, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(15, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ("123355559012345", read_buffer);
-
- // Write 4 bytes at offset 20 (-> length=24).
- data = "XXXX";
- Write(20, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 24, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(24, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ(std::string("123355559012345\0\0\0\0\0XXXX", 24), read_buffer);
-
- delegate()->set_available_space(5);
-
- // Quota error case. Write 7 bytes at offset 23 (-> length is unchanged)
- data = "ABCDEFG";
- Write(23, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
- EXPECT_EQ(5, delegate()->available_space());
- reset_results();
-
- // Overlapping write. Write 6 bytes at offset 2 (-> length is unchanged)
- data = "ABCDEF";
- Write(2, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(5, delegate()->available_space());
- reset_results();
-
- // Overlapping + extending the file size, but within the quota.
- // Write 6 bytes at offset 23 (-> length=29).
- Write(23, data);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(static_cast<int>(data.size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(0, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(29, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ(std::string("12ABCDEF9012345\0\0\0\0\0XXXABCDEF", 29),
- read_buffer);
- }
-
- void SetLengthTestBody() {
- delegate()->set_available_space(100);
-
- SetLength(0);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(0, GetPlatformFileSize());
- EXPECT_EQ(100, delegate()->available_space());
- reset_results();
-
- SetLength(8);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 8, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(8, GetPlatformFileSize());
-
- SetLength(16);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 16, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(16, GetPlatformFileSize());
-
- SetLength(4);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100 - 4, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(4, GetPlatformFileSize());
-
- SetLength(0);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- EXPECT_EQ(100, delegate()->available_space());
- reset_results();
-
- EXPECT_EQ(0, GetPlatformFileSize());
-
- delegate()->set_available_space(5);
-
- // Quota error case.
- SetLength(7);
- base::MessageLoop::current()->RunUntilIdle();
- ASSERT_EQ(1U, num_results());
- EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
- EXPECT_EQ(5, delegate()->available_space());
- reset_results();
- }
-
- QuotaMockDelegate* delegate() {
- return delegate_;
- }
-
- void Write(int64_t offset, const std::string& data) {
- ASSERT_TRUE(quota_file_io_->Write(
- offset, data.c_str(), data.size(),
- base::Bind(&QuotaFileIOTest::DidWrite, weak_factory_.GetWeakPtr())));
- }
-
- void SetLength(int64_t length) {
- ASSERT_TRUE(quota_file_io_->SetLength(
- length,
- base::Bind(&QuotaFileIOTest::DidSetLength,
- weak_factory_.GetWeakPtr())));
- }
-
- void DidWrite(PlatformFileError status, int bytes_written) {
- status_.push_back(status);
- bytes_written_.push_back(bytes_written);
- }
-
- void DidSetLength(PlatformFileError status) {
- status_.push_back(status);
- }
-
- size_t num_results() const { return status_.size(); }
- const std::deque<int>& bytes_written() const { return bytes_written_; }
- const std::deque<PlatformFileError>& status() const { return status_; }
-
- void reset_results() {
- bytes_written_.clear();
- status_.clear();
- }
-
- void pop_result() {
- bytes_written_.pop_front();
- status_.pop_front();
- }
-
- void ReadPlatformFile(std::string* data) {
- data->clear();
- char buf[256];
- int32_t read_offset = 0;
- for (;;) {
- int rv = base::ReadPlatformFile(file_, read_offset, buf, sizeof(buf));
- ASSERT_GE(rv, 0);
- if (rv == 0)
- break;
- read_offset += rv;
- data->append(buf, rv);
- }
- }
-
- int64_t GetPlatformFileSize() {
- base::PlatformFileInfo info;
- EXPECT_TRUE(base::GetPlatformFileInfo(file_, &info));
- return info.size;
- }
-
- void SetPlatformFileSize(int64_t length) {
- EXPECT_TRUE(base::TruncatePlatformFile(file_, length));
- }
-
- private:
- base::ScopedTempDir dir_;
- PlatformFile file_;
- scoped_ptr<QuotaFileIO> quota_file_io_;
- std::deque<int> bytes_written_;
- std::deque<PlatformFileError> status_;
- QuotaMockDelegate* delegate_;
- base::WeakPtrFactory<QuotaFileIOTest> weak_factory_;
-};
-
-TEST_F(QuotaFileIOTest, Write) {
- WriteTestBody();
-}
-
-TEST_F(QuotaFileIOTest, SetLength) {
- SetLengthTestBody();
-}
-
-TEST_F(QuotaFileIOTest, ParallelWrites) {
- delegate()->set_available_space(22);
- std::string read_buffer;
-
- const std::string data1[] = {
- std::string("12345678"),
- std::string("55555"),
- std::string("9012345"),
- };
- Write(0, data1[0]);
- Write(5, data1[1]);
- Write(8, data1[2]);
- base::MessageLoop::current()->RunUntilIdle();
-
- ASSERT_EQ(ARRAYSIZE_UNSAFE(data1), num_results());
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data1); ++i) {
- EXPECT_EQ(static_cast<int>(data1[i].size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- pop_result();
- }
-
- EXPECT_EQ(22 - 15, delegate()->available_space());
- EXPECT_EQ(15, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ("123455559012345", read_buffer);
-
- // The second write will fail for quota error.
- const std::string data2[] = {
- std::string("33"),
- std::string("XXXX"),
- };
- Write(2, data2[0]);
- Write(20, data2[1]);
- base::MessageLoop::current()->RunUntilIdle();
-
- ASSERT_EQ(ARRAYSIZE_UNSAFE(data2), num_results());
- EXPECT_EQ(static_cast<int>(data2[0].size()), bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_OK, status().front());
- pop_result();
- EXPECT_EQ(0, bytes_written().front());
- EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status().front());
- pop_result();
-
- EXPECT_EQ(22 - 15, delegate()->available_space());
- EXPECT_EQ(15, GetPlatformFileSize());
- ReadPlatformFile(&read_buffer);
- EXPECT_EQ("123355559012345", read_buffer);
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/pepper/quota_reservation.cc b/content/browser/renderer_host/pepper/quota_reservation.cc
new file mode 100644
index 0000000000..ed2821209c
--- /dev/null
+++ b/content/browser/renderer_host/pepper/quota_reservation.cc
@@ -0,0 +1,129 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/pepper/quota_reservation.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "content/public/browser/browser_thread.h"
+#include "webkit/browser/fileapi/quota/open_file_handle.h"
+#include "webkit/browser/fileapi/quota/quota_reservation.h"
+#include "webkit/common/fileapi/file_system_util.h"
+
+namespace content {
+
+// static
+scoped_refptr<QuotaReservation> QuotaReservation::Create(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ const GURL& origin_url,
+ fileapi::FileSystemType type) {
+ return scoped_refptr<QuotaReservation>(new QuotaReservation(
+ file_system_context, origin_url, type));
+}
+
+QuotaReservation::QuotaReservation(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ const GURL& origin_url,
+ fileapi::FileSystemType file_system_type)
+ : file_system_context_(file_system_context) {
+ quota_reservation_ =
+ file_system_context->CreateQuotaReservationOnFileTaskRunner(
+ origin_url,
+ file_system_type);
+}
+
+// For unit testing only.
+QuotaReservation::QuotaReservation(
+ scoped_refptr<fileapi::QuotaReservation> quota_reservation,
+ const GURL& /* origin_url */,
+ fileapi::FileSystemType /* file_system_type */)
+ : quota_reservation_(quota_reservation) {
+}
+
+QuotaReservation::~QuotaReservation() {
+ // We should have no open files at this point.
+ DCHECK(files_.size() == 0);
+ for (FileMap::iterator it = files_.begin(); it != files_.end(); ++ it)
+ delete it->second;
+}
+
+int64_t QuotaReservation::OpenFile(int32_t id,
+ const base::FilePath& file_path) {
+ scoped_ptr<fileapi::OpenFileHandle> file_handle =
+ quota_reservation_->GetOpenFileHandle(file_path);
+ std::pair<FileMap::iterator, bool> insert_result =
+ files_.insert(std::make_pair(id, file_handle.get()));
+ if (insert_result.second) {
+ int64_t max_written_offset = file_handle->base_file_size();
+ ignore_result(file_handle.release());
+ return max_written_offset;
+ }
+ NOTREACHED();
+ return 0;
+}
+
+void QuotaReservation::CloseFile(int32_t id,
+ int64_t max_written_offset) {
+ FileMap::iterator it = files_.find(id);
+ if (it != files_.end()) {
+ it->second->UpdateMaxWrittenOffset(max_written_offset);
+ files_.erase(it);
+ } else {
+ NOTREACHED();
+ }
+}
+
+void QuotaReservation::ReserveQuota(
+ int64_t amount,
+ const OffsetMap& max_written_offsets,
+ const ReserveQuotaCallback& callback) {
+ for (FileMap::iterator it = files_.begin(); it != files_.end(); ++ it) {
+ OffsetMap::const_iterator offset_it = max_written_offsets.find(it->first);
+ if (offset_it != max_written_offsets.end())
+ it->second->UpdateMaxWrittenOffset(offset_it->second);
+ else
+ NOTREACHED();
+ }
+
+ quota_reservation_->RefreshReservation(
+ amount,
+ base::Bind(&QuotaReservation::GotReservedQuota,
+ this,
+ callback));
+}
+
+void QuotaReservation::GotReservedQuota(
+ const ReserveQuotaCallback& callback,
+ base::PlatformFileError error) {
+ OffsetMap max_written_offsets;
+ for (FileMap::iterator it = files_.begin(); it != files_.end(); ++ it) {
+ max_written_offsets.insert(
+ std::make_pair(it->first, it->second->base_file_size()));
+ }
+
+ if (file_system_context_) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback,
+ quota_reservation_->remaining_quota(),
+ max_written_offsets));
+ } else {
+ // Unit testing code path.
+ callback.Run(quota_reservation_->remaining_quota(), max_written_offsets);
+ }
+}
+
+void QuotaReservation::DeleteOnCorrectThread() const {
+ if (file_system_context_) {
+ file_system_context_->default_file_task_runner()->DeleteSoon(
+ FROM_HERE,
+ this);
+ } else {
+ // Unit testing code path.
+ delete this;
+ }
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/pepper/quota_reservation.h b/content/browser/renderer_host/pepper/quota_reservation.h
new file mode 100644
index 0000000000..bd7e0eac58
--- /dev/null
+++ b/content/browser/renderer_host/pepper/quota_reservation.h
@@ -0,0 +1,100 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_RESERVATION_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_RESERVATION_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/platform_file.h"
+#include "content/common/content_export.h"
+#include "ppapi/c/pp_stdint.h" // For int64_t on Windows.
+#include "url/gurl.h"
+#include "webkit/browser/fileapi/file_system_context.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace fileapi {
+class OpenFileHandle;
+class QuotaReservation;
+}
+
+namespace content {
+
+struct QuotaReservationDeleter;
+
+// This class holds a QuotaReservation and manages OpenFileHandles for checking
+// quota. It should be created, used, and destroyed on a FileSystemContext's
+// default_file_task_runner() instance. This is a RefCountedThreadSafe object
+// because it needs to be passed to the file thread and kept alive during
+// potentially long-running quota operations.
+class CONTENT_EXPORT QuotaReservation
+ : public base::RefCountedThreadSafe<QuotaReservation,
+ QuotaReservationDeleter> {
+ public:
+ // Static method to facilitate construction on the file task runner.
+ static scoped_refptr<QuotaReservation> Create(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ const GURL& origin_url,
+ fileapi::FileSystemType file_system_type);
+
+ // Opens a file with the given id and path and returns its current size.
+ int64_t OpenFile(int32_t id, const base::FilePath& file_path);
+ // Closes the file opened by OpenFile with the given id.
+ void CloseFile(int32_t id, int64_t max_written_offset);
+ // Refreshes the quota reservation to a new amount. A map that associates file
+ // ids with maximum written offsets is provided as input. The callback will
+ // receive a similar map with the updated file sizes.
+ typedef std::map<int32_t, int64_t> OffsetMap;
+ typedef base::Callback<void(int64_t, const OffsetMap&)> ReserveQuotaCallback;
+ void ReserveQuota(int64_t amount,
+ const OffsetMap& max_written_offsets,
+ const ReserveQuotaCallback& callback);
+ private:
+ friend class base::RefCountedThreadSafe<QuotaReservation,
+ QuotaReservationDeleter>;
+ friend class base::DeleteHelper<QuotaReservation>;
+ friend struct QuotaReservationDeleter;
+ friend class QuotaReservationTest;
+
+ QuotaReservation(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ const GURL& origin_url,
+ fileapi::FileSystemType file_system_type);
+
+ // For unit testing only. A QuotaReservation intended for unit testing will
+ // have file_system_context_ == NULL.
+ QuotaReservation(
+ scoped_refptr<fileapi::QuotaReservation> quota_reservation,
+ const GURL& origin_url,
+ fileapi::FileSystemType file_system_type);
+
+ ~QuotaReservation();
+
+ void GotReservedQuota(const ReserveQuotaCallback& callback,
+ base::PlatformFileError error);
+
+ void DeleteOnCorrectThread() const;
+
+ scoped_refptr<fileapi::FileSystemContext> file_system_context_;
+ scoped_refptr<fileapi::QuotaReservation> quota_reservation_;
+ typedef std::map<int32_t, fileapi::OpenFileHandle*> FileMap;
+ FileMap files_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuotaReservation);
+};
+
+struct QuotaReservationDeleter {
+ static void Destruct(const QuotaReservation* quota_reservation) {
+ quota_reservation->DeleteOnCorrectThread();
+ }
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_QUOTA_RESERVATION_H_
diff --git a/content/browser/renderer_host/pepper/quota_reservation_unittest.cc b/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
new file mode 100644
index 0000000000..a9a5f71008
--- /dev/null
+++ b/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
@@ -0,0 +1,238 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/pepper/quota_reservation.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/browser/fileapi/quota/quota_reservation.h"
+
+using fileapi::FileSystemType;
+using fileapi::QuotaReservationManager;
+
+namespace content {
+
+namespace {
+
+const char kOrigin[] = "http://example.com";
+const FileSystemType kType = fileapi::kFileSystemTypeTemporary;
+
+const base::FilePath::StringType file1_name = FILE_PATH_LITERAL("file1");
+const base::FilePath::StringType file2_name = FILE_PATH_LITERAL("file2");
+const base::FilePath::StringType file3_name = FILE_PATH_LITERAL("file3");
+const int kFile1ID = 1;
+const int kFile2ID = 2;
+const int kFile3ID = 3;
+
+class FakeBackend : public QuotaReservationManager::QuotaBackend {
+ public:
+ FakeBackend() {}
+ virtual ~FakeBackend() {}
+
+ virtual void ReserveQuota(
+ const GURL& origin,
+ FileSystemType type,
+ int64 delta,
+ const QuotaReservationManager::ReserveQuotaCallback& callback) OVERRIDE {
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(callback), base::PLATFORM_FILE_OK));
+ }
+
+ virtual void ReleaseReservedQuota(const GURL& origin,
+ FileSystemType type,
+ int64 size) OVERRIDE {
+ }
+
+ virtual void CommitQuotaUsage(const GURL& origin,
+ FileSystemType type,
+ int64 delta) OVERRIDE {
+ }
+
+ virtual void IncrementDirtyCount(const GURL& origin,
+ FileSystemType type) OVERRIDE {}
+ virtual void DecrementDirtyCount(const GURL& origin,
+ FileSystemType type) OVERRIDE {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeBackend);
+};
+
+} // namespace
+
+class QuotaReservationTest : public testing::Test {
+ public:
+ QuotaReservationTest() {}
+ virtual ~QuotaReservationTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(work_dir_.CreateUniqueTempDir());
+
+ reservation_manager_.reset(new QuotaReservationManager(
+ scoped_ptr<QuotaReservationManager::QuotaBackend>(new FakeBackend)));
+ }
+
+ virtual void TearDown() OVERRIDE {
+ reservation_manager_.reset();
+ }
+
+ base::FilePath MakeFilePath(base::FilePath::StringType file_name) {
+ return work_dir_.path().Append(file_name);
+ }
+
+ scoped_refptr<QuotaReservation> CreateQuotaReservation(
+ scoped_refptr<fileapi::QuotaReservation> reservation,
+ const GURL& origin,
+ FileSystemType type) {
+ // Sets reservation_ as a side effect.
+ return scoped_refptr<QuotaReservation>(
+ new QuotaReservation(reservation, origin, type));
+ }
+
+ void SetFileSize(const base::FilePath::StringType& file_name, int64 size) {
+ bool created = false;
+ base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
+ base::PlatformFile file = CreatePlatformFile(
+ MakeFilePath(file_name),
+ base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE,
+ &created, &error);
+ ASSERT_EQ(base::PLATFORM_FILE_OK, error);
+ ASSERT_TRUE(base::TruncatePlatformFile(file, size));
+ ASSERT_TRUE(base::ClosePlatformFile(file));
+ }
+
+ QuotaReservationManager* reservation_manager() {
+ return reservation_manager_.get();
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+ base::ScopedTempDir work_dir_;
+ scoped_ptr<fileapi::QuotaReservationManager> reservation_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuotaReservationTest);
+};
+
+void GotReservedQuota(
+ int64* reserved_quota_ptr,
+ QuotaReservation::OffsetMap* maximum_written_offsets_ptr,
+ int64 reserved_quota,
+ const QuotaReservation::OffsetMap& maximum_written_offsets) {
+ *reserved_quota_ptr = reserved_quota;
+ *maximum_written_offsets_ptr = maximum_written_offsets;
+}
+
+void ReserveQuota(
+ scoped_refptr<QuotaReservation> quota_reservation,
+ int64 amount,
+ int64* reserved_quota,
+ QuotaReservation::OffsetMap* max_written_offsets) {
+ quota_reservation->ReserveQuota(amount,
+ *max_written_offsets,
+ base::Bind(&GotReservedQuota,
+ reserved_quota,
+ max_written_offsets));
+ base::RunLoop().RunUntilIdle();
+}
+
+// Tests that:
+// 1) We can reserve quota with no files open.
+// 2) Open a file, grow it, close it, and reserve quota with correct sizes.
+TEST_F(QuotaReservationTest, DISABLED_ReserveQuota) {
+ GURL origin(kOrigin);
+ FileSystemType type = kType;
+
+ scoped_refptr<fileapi::QuotaReservation> reservation(
+ reservation_manager()->CreateReservation(origin, type));
+ scoped_refptr<QuotaReservation> test =
+ CreateQuotaReservation(reservation, origin, type);
+
+ // Reserve quota with no files open.
+ int64 amount = 100;
+ int64 reserved_quota;
+ QuotaReservation::OffsetMap max_written_offsets;
+ ReserveQuota(test, amount, &reserved_quota, &max_written_offsets);
+ EXPECT_EQ(amount, reserved_quota);
+ EXPECT_EQ(0U, max_written_offsets.size());
+
+ // Open a file, refresh the reservation, extend the file, and close it.
+ int64 file_size = 10;
+ SetFileSize(file1_name, file_size);
+ int64 open_file_size = test->OpenFile(kFile1ID, MakeFilePath(file1_name));
+ EXPECT_EQ(file_size, open_file_size);
+
+ max_written_offsets[kFile1ID] = file_size; // 1 file open.
+ ReserveQuota(test, amount, &reserved_quota, &max_written_offsets);
+ EXPECT_EQ(amount, reserved_quota);
+ EXPECT_EQ(1U, max_written_offsets.size());
+ EXPECT_EQ(file_size, max_written_offsets[kFile1ID]);
+
+ int64 new_file_size = 30;
+ SetFileSize(file1_name, new_file_size);
+
+ EXPECT_EQ(amount, reservation->remaining_quota());
+ test->CloseFile(kFile1ID, new_file_size);
+ EXPECT_EQ(amount - (new_file_size - file_size),
+ reservation->remaining_quota());
+}
+
+// Tests that:
+// 1) We can open and close multiple files.
+TEST_F(QuotaReservationTest, DISABLED_MultipleFiles) {
+ GURL origin(kOrigin);
+ FileSystemType type = kType;
+
+ scoped_refptr<fileapi::QuotaReservation> reservation(
+ reservation_manager()->CreateReservation(origin, type));
+ scoped_refptr<QuotaReservation> test =
+ CreateQuotaReservation(reservation, origin, type);
+
+ // Open some files of different sizes.
+ int64 file1_size = 10;
+ SetFileSize(file1_name, file1_size);
+ int64 open_file1_size = test->OpenFile(kFile1ID, MakeFilePath(file1_name));
+ EXPECT_EQ(file1_size, open_file1_size);
+ int64 file2_size = 20;
+ SetFileSize(file2_name, file2_size);
+ int64 open_file2_size = test->OpenFile(kFile2ID, MakeFilePath(file2_name));
+ EXPECT_EQ(file2_size, open_file2_size);
+ int64 file3_size = 30;
+ SetFileSize(file3_name, file3_size);
+ int64 open_file3_size = test->OpenFile(kFile3ID, MakeFilePath(file3_name));
+ EXPECT_EQ(file3_size, open_file3_size);
+
+ // Reserve quota.
+ int64 amount = 100;
+ int64 reserved_quota;
+ QuotaReservation::OffsetMap max_written_offsets;
+ max_written_offsets[kFile1ID] = file1_size; // 3 files open.
+ max_written_offsets[kFile2ID] = file2_size;
+ max_written_offsets[kFile3ID] = file3_size;
+
+ ReserveQuota(test, amount, &reserved_quota, &max_written_offsets);
+ EXPECT_EQ(amount, reserved_quota);
+ EXPECT_EQ(3U, max_written_offsets.size());
+ EXPECT_EQ(file1_size, max_written_offsets[kFile1ID]);
+ EXPECT_EQ(file2_size, max_written_offsets[kFile2ID]);
+ EXPECT_EQ(file3_size, max_written_offsets[kFile3ID]);
+
+ test->CloseFile(kFile2ID, file2_size);
+
+ max_written_offsets.erase(max_written_offsets.find(kFile2ID));
+ ReserveQuota(test, amount, &reserved_quota, &max_written_offsets);
+ EXPECT_EQ(amount, reserved_quota);
+ EXPECT_EQ(2U, max_written_offsets.size());
+ EXPECT_EQ(file1_size, max_written_offsets[kFile1ID]);
+ EXPECT_EQ(file3_size, max_written_offsets[kFile3ID]);
+
+ test->CloseFile(kFile1ID, file1_size);
+ test->CloseFile(kFile3ID, file3_size);
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 3aca534e48..dd6a3c3079 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -33,6 +33,8 @@
#include "content/common/child_process_messages.h"
#include "content/common/cookie_data.h"
#include "content/common/desktop_notification_messages.h"
+#include "content/common/frame_messages.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
#include "content/common/media/media_param_traits.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_child_process_host.h"
@@ -68,7 +70,9 @@
#include "ui/gfx/color_profile.h"
#if defined(OS_MACOSX)
+#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
#include "content/common/mac/font_descriptor.h"
+#include "ui/gl/io_surface_support_mac.h"
#else
#include "gpu/GLES2/gl2extchromium.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -204,6 +208,23 @@ class OpenChannelToPpapiBrokerCallback
int routing_id_;
};
+#if defined(OS_MACOSX)
+void AddBooleanValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ bool value) {
+ CFDictionaryAddValue(
+ dictionary, key, value ? kCFBooleanTrue : kCFBooleanFalse);
+}
+
+void AddIntegerValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ int32 value) {
+ base::ScopedCFTypeRef<CFNumberRef> number(
+ CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
+ CFDictionaryAddValue(dictionary, key, number.get());
+}
+#endif
+
} // namespace
class RenderMessageFilter::OpenChannelToNpapiPluginCallback
@@ -276,8 +297,8 @@ class RenderMessageFilter::OpenChannelToNpapiPluginCallback
private:
void WriteReplyAndDeleteThis(const IPC::ChannelHandle& handle) {
- ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(),
- handle, info_);
+ FrameHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg(),
+ handle, info_);
filter()->OnCompletedOpenChannelToNpapiPlugin(this);
SendReplyAndDeleteThis();
}
@@ -380,8 +401,8 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl)
#if defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginInfo, OnGetPluginInfo)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin,
+ IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPlugin,
OnOpenChannelToPlugin)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPepperPlugin,
OnOpenChannelToPepperPlugin)
@@ -714,7 +735,7 @@ void RenderMessageFilter::GetPluginsCallback(
}
void RenderMessageFilter::OnGetPluginInfo(
- int routing_id,
+ int render_frame_id,
const GURL& url,
const GURL& page_url,
const std::string& mime_type,
@@ -723,12 +744,12 @@ void RenderMessageFilter::OnGetPluginInfo(
std::string* actual_mime_type) {
bool allow_wildcard = true;
*found = plugin_service_->GetPluginInfo(
- render_process_id_, routing_id, resource_context_,
+ render_process_id_, render_frame_id, resource_context_,
url, page_url, mime_type, allow_wildcard,
NULL, info, actual_mime_type);
}
-void RenderMessageFilter::OnOpenChannelToPlugin(int routing_id,
+void RenderMessageFilter::OnOpenChannelToPlugin(int render_frame_id,
const GURL& url,
const GURL& policy_url,
const std::string& mime_type,
@@ -738,7 +759,7 @@ void RenderMessageFilter::OnOpenChannelToPlugin(int routing_id,
DCHECK(!ContainsKey(plugin_host_clients_, client));
plugin_host_clients_.insert(client);
plugin_service_->OpenChannelToNpapiPlugin(
- render_process_id_, routing_id,
+ render_process_id_, render_frame_id,
url, policy_url, mime_type, client);
}
@@ -843,7 +864,7 @@ void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) {
void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message,
const GURL& url,
const Referrer& referrer,
- const string16& suggested_name) {
+ const base::string16& suggested_name) {
scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
save_info->suggested_name = suggested_name;
scoped_ptr<net::URLRequest> request(
@@ -1112,7 +1133,7 @@ void RenderMessageFilter::OnDidLose3DContext(
#if defined(OS_WIN)
void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font,
- const string16& str) {
+ const base::string16& str) {
// First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
// Except that for True Type fonts,
// GetTextMetrics will not load the font in memory.
@@ -1156,21 +1177,78 @@ void RenderMessageFilter::OnWebAudioMediaCodec(
#endif
void RenderMessageFilter::OnAllocateGpuMemoryBuffer(
- uint32 buffer_size,
+ uint32 width,
+ uint32 height,
+ uint32 internalformat,
gfx::GpuMemoryBufferHandle* handle) {
- // TODO(reveman): Implement allocation of real GpuMemoryBuffer.
- // Currently this function creates a fake GpuMemoryBuffer that is
- // backed by shared memory and requires an upload before it can
- // be used as a texture. The plan is to instead have this function
- // allocate a real GpuMemoryBuffer in whatever form is supported
- // by platform and drivers.
- //
- // Note: |buffer_size| likely needs to be replaced by a more
- // specific buffer description but is enough for the shared memory
- // backed GpuMemoryBuffer currently returned.
+ if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) {
+ handle->type = gfx::EMPTY_BUFFER;
+ return;
+ }
+
+#if defined(OS_MACOSX)
+ if (GpuMemoryBufferImplIOSurface::IsFormatSupported(internalformat)) {
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+ if (io_surface_support) {
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
+ properties.reset(
+ CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceWidth(),
+ width);
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceHeight(),
+ height);
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceBytesPerElement(),
+ GpuMemoryBufferImpl::BytesPerPixel(internalformat));
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfacePixelFormat(),
+ GpuMemoryBufferImplIOSurface::PixelFormat(
+ internalformat));
+ // TODO(reveman): Remove this when using a mach_port_t to transfer
+ // IOSurface to renderer process. crbug.com/323304
+ AddBooleanValue(properties,
+ io_surface_support->GetKIOSurfaceIsGlobal(),
+ true);
+
+ base::ScopedCFTypeRef<CFTypeRef> io_surface(
+ io_surface_support->IOSurfaceCreate(properties));
+ if (io_surface) {
+ handle->type = gfx::IO_SURFACE_BUFFER;
+ handle->io_surface_id = io_surface_support->IOSurfaceGetID(io_surface);
+
+ // TODO(reveman): This makes the assumption that the renderer will
+ // grab a reference to the surface before sending another message.
+ // crbug.com/325045
+ last_io_surface_ = io_surface;
+ return;
+ }
+ }
+ }
+#endif
+
+ uint64 stride = static_cast<uint64>(width) *
+ GpuMemoryBufferImpl::BytesPerPixel(internalformat);
+ if (stride > std::numeric_limits<uint32>::max()) {
+ handle->type = gfx::EMPTY_BUFFER;
+ return;
+ }
+
+ uint64 buffer_size = stride * static_cast<uint64>(height);
+ if (buffer_size > std::numeric_limits<size_t>::max()) {
+ handle->type = gfx::EMPTY_BUFFER;
+ return;
+ }
+
+ // Fallback to fake GpuMemoryBuffer that is backed by shared memory and
+ // requires an upload before it can be used as a texture.
handle->type = gfx::SHARED_MEMORY_BUFFER;
ChildProcessHostImpl::AllocateSharedMemory(
- buffer_size, PeerHandle(), &handle->handle);
+ static_cast<size_t>(buffer_size), PeerHandle(), &handle->handle);
}
} // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 526849e102..ce135d928f 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -30,6 +30,7 @@
#include "ui/surface/transport_dib.h"
#if defined(OS_MACOSX)
+#include "base/mac/scoped_cftyperef.h"
#include "content/common/mac/font_loader.h"
#endif
@@ -156,20 +157,20 @@ class RenderMessageFilter : public BrowserMessageFilter {
#if defined(OS_WIN)
void OnPreCacheFontCharacters(const LOGFONT& log_font,
- const string16& characters);
+ const base::string16& characters);
#endif
void OnGetPlugins(bool refresh, IPC::Message* reply_msg);
void GetPluginsCallback(IPC::Message* reply_msg,
const std::vector<WebPluginInfo>& plugins);
- void OnGetPluginInfo(int routing_id,
+ void OnGetPluginInfo(int render_frame_id,
const GURL& url,
const GURL& policy_url,
const std::string& mime_type,
bool* found,
WebPluginInfo* info,
std::string* actual_mime_type);
- void OnOpenChannelToPlugin(int routing_id,
+ void OnOpenChannelToPlugin(int render_frame_id,
const GURL& url,
const GURL& policy_url,
const std::string& mime_type,
@@ -190,7 +191,7 @@ class RenderMessageFilter : public BrowserMessageFilter {
void OnDownloadUrl(const IPC::Message& message,
const GURL& url,
const Referrer& referrer,
- const string16& suggested_name);
+ const base::string16& suggested_name);
void OnCheckNotificationPermission(const GURL& source_origin,
int* permission_level);
@@ -259,7 +260,9 @@ class RenderMessageFilter : public BrowserMessageFilter {
uint32_t data_size);
#endif
- void OnAllocateGpuMemoryBuffer(uint32 buffer_size,
+ void OnAllocateGpuMemoryBuffer(uint32 width,
+ uint32 height,
+ uint32 internalformat,
gfx::GpuMemoryBufferHandle* handle);
// Cached resource request dispatcher host and plugin service, guaranteed to
@@ -302,6 +305,10 @@ class RenderMessageFilter : public BrowserMessageFilter {
media::AudioManager* audio_manager_;
MediaInternals* media_internals_;
+#if defined(OS_MACOSX)
+ base::ScopedCFTypeRef<CFTypeRef> last_io_surface_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(RenderMessageFilter);
};
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 08e75cf2ad..231b59df69 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -101,7 +101,6 @@
#include "content/browser/speech/speech_recognition_dispatcher_host.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/streams/stream_context.h"
-#include "content/browser/tracing/trace_controller_impl.h"
#include "content/browser/tracing/trace_message_filter.h"
#include "content/browser/vibration/vibration_message_filter.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
@@ -669,7 +668,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID());
AddFilter(peer_connection_tracker_host_.get());
AddFilter(new MediaStreamDispatcherHost(
- GetID(), media_stream_manager));
+ GetID(), browser_context->GetResourceContext(), media_stream_manager));
AddFilter(
new DeviceRequestMessageFilter(resource_context, media_stream_manager));
#endif
@@ -823,6 +822,10 @@ bool RenderProcessHostImpl::WaitForBackingStoreMsg(
}
void RenderProcessHostImpl::ReceivedBadMessage() {
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))
+ return;
+
if (run_renderer_in_process()) {
// In single process mode it is better if we don't suicide but just
// crash.
@@ -966,7 +969,6 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableUnprefixedMediaSource,
switches::kDisableVp8AlphaPlayback,
switches::kDisableWebAnimationsCSS,
- switches::kDisableWebAudio,
switches::kDisableWebKitMediaSource,
switches::kDomAutomationController,
switches::kEnableAcceleratedFixedRootBackground,
@@ -1035,6 +1037,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kNoReferrers,
switches::kNoSandbox,
switches::kPpapiInProcess,
+ switches::kProfilerTiming,
switches::kRegisterPepperPlugins,
switches::kRendererAssertTest,
switches::kRendererStartupDialog,
@@ -1072,13 +1075,12 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
cc::switches::kEnablePerTilePainting,
cc::switches::kEnablePinchVirtualViewport,
cc::switches::kEnableTopControlsPositionCalculation,
- cc::switches::kForceDirectLayerDrawing,
- cc::switches::kLowResolutionContentsScaleFactor,
cc::switches::kMaxTilesForInterestArea,
cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
cc::switches::kNumRasterThreads,
cc::switches::kShowCompositedLayerBorders,
cc::switches::kShowFPSCounter,
+ cc::switches::kShowLayerAnimationBounds,
cc::switches::kShowNonOccludingRects,
cc::switches::kShowOccludingRects,
cc::switches::kShowPropertyChangedRects,
@@ -1123,6 +1125,13 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kMediaDrmEnableNonCompositing,
switches::kNetworkCountryIso,
#endif
+#if defined(OS_ANDROID) && defined(ARCH_CPU_X86)
+ switches::kEnableWebAudio,
+#else
+ // Need to be able to disable webaudio on other platforms where it
+ // is enabled by default.
+ switches::kDisableWebAudio,
+#endif
#if defined(OS_MACOSX)
// Allow this to be set when invoking the browser and relayed along.
switches::kEnableSandboxLogging,
@@ -1131,6 +1140,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kChildCleanExit,
#endif
#if defined(OS_WIN)
+ switches::kEnableDirectWrite,
switches::kEnableHighResolutionTime,
#endif
};
@@ -1191,8 +1201,11 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() {
if (!SuddenTerminationAllowed())
return false;
- ProcessDied(false /* already_dead */);
+ // Set this before ProcessDied() so observers can tell if the render process
+ // died due to fast shutdown versus another cause.
fast_shutdown_started_ = true;
+
+ ProcessDied(false /* already_dead */);
return true;
}
diff --git a/content/browser/renderer_host/render_sandbox_host_linux.cc b/content/browser/renderer_host/render_sandbox_host_linux.cc
index b35ac7365b..d17b1caa7c 100644
--- a/content/browser/renderer_host/render_sandbox_host_linux.cc
+++ b/content/browser/renderer_host/render_sandbox_host_linux.cc
@@ -241,7 +241,7 @@ class SandboxIPCProcess {
SendRendererReply(fds, reply, result_fd);
if (result_fd >= 0) {
- int err = HANDLE_EINTR(close(result_fd));
+ int err = IGNORE_EINTR(close(result_fd));
DCHECK(!err);
}
}
@@ -516,7 +516,7 @@ class SandboxIPCProcess {
SendRendererReply(fds, reply, font_fd);
if (font_fd >= 0) {
- if (HANDLE_EINTR(close(font_fd)) < 0)
+ if (IGNORE_EINTR(close(font_fd)) < 0)
PLOG(ERROR) << "close";
}
}
@@ -709,18 +709,17 @@ void RenderSandboxHostLinux::Init(const std::string& sandbox_path) {
childs_lifeline_fd_ = pipefds[1];
// We need to be monothreaded before we fork().
-#if !defined(TOOLKIT_GTK) && !defined(OS_CHROMEOS)
+#if !defined(TOOLKIT_GTK)
// Exclude gtk port as TestSuite in base/tests/test_suite.cc is calling
// gtk_init.
- // Exclude ChromeOS because KioskTest spawns EmbeddedTestServer.
// TODO(oshima): Remove ifdef when above issues are resolved.
DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle()));
#endif
pid_ = fork();
if (pid_ == 0) {
- if (HANDLE_EINTR(close(fds[0])) < 0)
+ if (IGNORE_EINTR(close(fds[0])) < 0)
DPLOG(ERROR) << "close";
- if (HANDLE_EINTR(close(pipefds[1])) < 0)
+ if (IGNORE_EINTR(close(pipefds[1])) < 0)
DPLOG(ERROR) << "close";
SandboxIPCProcess handler(child_lifeline_fd, browser_socket, sandbox_path);
@@ -731,9 +730,9 @@ void RenderSandboxHostLinux::Init(const std::string& sandbox_path) {
RenderSandboxHostLinux::~RenderSandboxHostLinux() {
if (initialized_) {
- if (HANDLE_EINTR(close(renderer_socket_)) < 0)
+ if (IGNORE_EINTR(close(renderer_socket_)) < 0)
PLOG(ERROR) << "close";
- if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0)
+ if (IGNORE_EINTR(close(childs_lifeline_fd_)) < 0)
PLOG(ERROR) << "close";
}
}
diff --git a/content/browser/renderer_host/render_view_host_delegate.cc b/content/browser/renderer_host/render_view_host_delegate.cc
index d7b8ba5374..4786909c92 100644
--- a/content/browser/renderer_host/render_view_host_delegate.cc
+++ b/content/browser/renderer_host/render_view_host_delegate.cc
@@ -24,8 +24,8 @@ bool RenderViewHostDelegate::OnMessageReceived(RenderViewHost* render_view_host,
}
bool RenderViewHostDelegate::AddMessageToConsole(
- int32 level, const string16& message, int32 line_no,
- const string16& source_id) {
+ int32 level, const base::string16& message, int32 line_no,
+ const base::string16& source_id) {
return false;
}
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index f3bf8aafea..a258c36740 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -151,14 +151,6 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// RenderView is going to be destroyed
virtual void RenderViewDeleted(RenderViewHost* render_view_host) {}
- // The RenderView started a provisional load for a given frame.
- virtual void DidStartProvisionalLoadForFrame(
- RenderViewHost* render_view_host,
- int64 frame_id,
- int64 parent_frame_id,
- bool main_frame,
- const GURL& url) {}
-
// The RenderView processed a redirect during a provisional load.
//
// TODO(creis): Remove this method and have the pre-rendering code listen to
@@ -195,7 +187,7 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// The page's title was changed and should be updated.
virtual void UpdateTitle(RenderViewHost* render_view_host,
int32 page_id,
- const string16& title,
+ const base::string16& title,
base::i18n::TextDirection title_direction) {}
// The page's encoding was changed and should be updated.
@@ -281,23 +273,23 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// A javascript message, confirmation or prompt should be shown.
virtual void RunJavaScriptMessage(RenderViewHost* rvh,
- const string16& message,
- const string16& default_prompt,
+ const base::string16& message,
+ const base::string16& default_prompt,
const GURL& frame_url,
JavaScriptMessageType type,
IPC::Message* reply_msg,
bool* did_suppress_message) {}
virtual void RunBeforeUnloadConfirm(RenderViewHost* rvh,
- const string16& message,
+ const base::string16& message,
bool is_reload,
IPC::Message* reply_msg) {}
// A message was added to to the console.
virtual bool AddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id);
+ const base::string16& source_id);
// Return a dummy RendererPreferences object that will be used by the renderer
// associated with the owning RenderViewHost.
@@ -382,8 +374,9 @@ class CONTENT_EXPORT RenderViewHostDelegate {
virtual void LostMouseLock() {}
// The page is trying to open a new page (e.g. a popup window). The window
- // should be created associated with the given route, but it should not be
- // shown yet. That should happen in response to ShowCreatedWindow.
+ // should be created associated with the given |route_id| in process
+ // |render_process_id|, but it should not be shown yet. That should happen in
+ // response to ShowCreatedWindow.
// |params.window_container_type| describes the type of RenderViewHost
// container that is requested -- in particular, the window.open call may
// have specified 'background' and 'persistent' in the feature string.
@@ -394,21 +387,24 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// Note: this is not called "CreateWindow" because that will clash with
// the Windows function which is actually a #define.
virtual void CreateNewWindow(
+ int render_process_id,
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) {}
// The page is trying to open a new widget (e.g. a select popup). The
- // widget should be created associated with the given route, but it should
- // not be shown yet. That should happen in response to ShowCreatedWidget.
+ // widget should be created associated with the given |route_id| in the
+ // process |render_process_id|, but it should not be shown yet. That should
+ // happen in response to ShowCreatedWidget.
// |popup_type| indicates if the widget is a popup and what kind of popup it
// is (select, autofill...).
- virtual void CreateNewWidget(int route_id,
+ virtual void CreateNewWidget(int render_process_id,
+ int route_id,
blink::WebPopupType popup_type) {}
// Creates a full screen RenderWidget. Similar to above.
- virtual void CreateNewFullscreenWidget(int route_id) {}
+ virtual void CreateNewFullscreenWidget(int render_process_id, int route_id) {}
// Show a previously created page with the specified disposition and bounds.
// The window is identified by the route_id passed to CreateNewWindow.
diff --git a/content/browser/renderer_host/render_view_host_factory.cc b/content/browser/renderer_host/render_view_host_factory.cc
index 5cffd134b8..fe51c7efe6 100644
--- a/content/browser/renderer_host/render_view_host_factory.cc
+++ b/content/browser/renderer_host/render_view_host_factory.cc
@@ -16,17 +16,19 @@ RenderViewHostFactory* RenderViewHostFactory::factory_ = NULL;
RenderViewHost* RenderViewHostFactory::Create(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
bool swapped_out,
bool hidden) {
if (factory_) {
- return factory_->CreateRenderViewHost(instance, delegate, widget_delegate,
- routing_id, main_frame_routing_id,
- swapped_out);
+ return factory_->CreateRenderViewHost(instance, delegate, frame_delegate,
+ widget_delegate, routing_id,
+ main_frame_routing_id, swapped_out);
}
- return new RenderViewHostImpl(instance, delegate, widget_delegate, routing_id,
+ return new RenderViewHostImpl(instance, delegate, frame_delegate,
+ widget_delegate, routing_id,
main_frame_routing_id, swapped_out, hidden);
}
diff --git a/content/browser/renderer_host/render_view_host_factory.h b/content/browser/renderer_host/render_view_host_factory.h
index b0466355d4..cf6a0f1b3f 100644
--- a/content/browser/renderer_host/render_view_host_factory.h
+++ b/content/browser/renderer_host/render_view_host_factory.h
@@ -9,6 +9,7 @@
#include "content/common/content_export.h"
namespace content {
+class RenderFrameHostDelegate;
class RenderViewHost;
class RenderViewHostDelegate;
class RenderWidgetHostDelegate;
@@ -26,6 +27,7 @@ class RenderViewHostFactory {
static RenderViewHost* Create(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
@@ -46,6 +48,7 @@ class RenderViewHostFactory {
virtual RenderViewHost* CreateRenderViewHost(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index b19cd19ec4..491944e87a 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -159,6 +159,7 @@ RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
RenderViewHostImpl::RenderViewHostImpl(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
@@ -193,7 +194,11 @@ RenderViewHostImpl::RenderViewHostImpl(
main_frame_routing_id = GetProcess()->GetNextRoutingID();
main_render_frame_host_ = RenderFrameHostFactory::Create(
- this, delegate_->GetFrameTree(), main_frame_routing_id, is_swapped_out_);
+ this, frame_delegate, delegate_->GetFrameTree(),
+ delegate_->GetFrameTree()->root(),
+ main_frame_routing_id, is_swapped_out_);
+ delegate_->GetFrameTree()->root()->set_render_frame_host(
+ main_render_frame_host_.get(), false);
GetProcess()->EnableSendQueue();
@@ -243,7 +248,7 @@ SiteInstance* RenderViewHostImpl::GetSiteInstance() const {
}
bool RenderViewHostImpl::CreateRenderView(
- const string16& frame_name,
+ const base::string16& frame_name,
int opener_route_id,
int32 max_page_id) {
TRACE_EVENT0("renderer_host", "RenderViewHostImpl::CreateRenderView");
@@ -343,8 +348,13 @@ WebPreferences RenderViewHostImpl::GetWebkitPrefs(const GURL& url) {
!command_line.HasSwitch(switches::kDisableLocalStorage);
prefs.databases_enabled =
!command_line.HasSwitch(switches::kDisableDatabases);
+#if defined(OS_ANDROID) && defined(ARCH_CPU_X86)
+ prefs.webaudio_enabled =
+ command_line.HasSwitch(switches::kEnableWebAudio);
+#else
prefs.webaudio_enabled =
!command_line.HasSwitch(switches::kDisableWebAudio);
+#endif
prefs.experimental_webgl_enabled =
GpuProcessHost::gpu_enabled() &&
@@ -948,8 +958,9 @@ void RenderViewHostImpl::DesktopNotificationPostDisplay(int callback_context) {
callback_context));
}
-void RenderViewHostImpl::DesktopNotificationPostError(int notification_id,
- const string16& message) {
+void RenderViewHostImpl::DesktopNotificationPostError(
+ int notification_id,
+ const base::string16& message) {
Send(new DesktopNotificationMsg_PostError(
GetRoutingID(), notification_id, message));
}
@@ -965,15 +976,15 @@ void RenderViewHostImpl::DesktopNotificationPostClick(int notification_id) {
}
void RenderViewHostImpl::ExecuteJavascriptInWebFrame(
- const string16& frame_xpath,
- const string16& jscript) {
+ const base::string16& frame_xpath,
+ const base::string16& jscript) {
Send(new ViewMsg_ScriptEvalRequest(GetRoutingID(), frame_xpath, jscript,
0, false));
}
void RenderViewHostImpl::ExecuteJavascriptInWebFrameCallbackResult(
- const string16& frame_xpath,
- const string16& jscript,
+ const base::string16& frame_xpath,
+ const base::string16& jscript,
const JavascriptResultCallback& callback) {
static int next_id = 1;
int key = next_id++;
@@ -982,9 +993,10 @@ void RenderViewHostImpl::ExecuteJavascriptInWebFrameCallbackResult(
javascript_callbacks_.insert(std::make_pair(key, callback));
}
-void RenderViewHostImpl::JavaScriptDialogClosed(IPC::Message* reply_msg,
- bool success,
- const string16& user_input) {
+void RenderViewHostImpl::JavaScriptDialogClosed(
+ IPC::Message* reply_msg,
+ bool success,
+ const base::string16& user_input) {
GetProcess()->SetIgnoreInputEvents(false);
bool is_waiting =
is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_;
@@ -1179,10 +1191,6 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
if (delegate_->OnMessageReceived(this, msg))
return true;
- // TODO(jochen): Consider removing message handlers that only add a this
- // pointer and forward the messages to the RenderViewHostDelegate. The
- // respective delegates can handle the messages themselves in their
- // OnMessageReceived implementation.
bool handled = true;
bool msg_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderViewHostImpl, msg, msg_is_ok)
@@ -1321,17 +1329,18 @@ void RenderViewHostImpl::CreateNewWindow(
FilterURL(policy, GetProcess(), true,
&validated_params.opener_security_origin);
- delegate_->CreateNewWindow(route_id, main_frame_route_id,
- validated_params, session_storage_namespace);
+ delegate_->CreateNewWindow(
+ GetProcess()->GetID(), route_id, main_frame_route_id, validated_params,
+ session_storage_namespace);
}
void RenderViewHostImpl::CreateNewWidget(int route_id,
blink::WebPopupType popup_type) {
- delegate_->CreateNewWidget(route_id, popup_type);
+ delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, popup_type);
}
void RenderViewHostImpl::CreateNewFullscreenWidget(int route_id) {
- delegate_->CreateNewFullscreenWidget(route_id);
+ delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id);
}
void RenderViewHostImpl::OnShowView(int route_id,
@@ -1410,8 +1419,7 @@ void RenderViewHostImpl::OnDidStartProvisionalLoadForFrame(
int64 parent_frame_id,
bool is_main_frame,
const GURL& url) {
- delegate_->DidStartProvisionalLoadForFrame(
- this, frame_id, parent_frame_id, is_main_frame, url);
+ NOTREACHED();
}
void RenderViewHostImpl::OnDidRedirectProvisionalLoad(
@@ -1535,7 +1543,7 @@ void RenderViewHostImpl::OnUpdateState(int32 page_id, const PageState& state) {
void RenderViewHostImpl::OnUpdateTitle(
int32 page_id,
- const string16& title,
+ const base::string16& title,
blink::WebTextDirection title_direction) {
if (title.length() > kMaxTitleChars) {
NOTREACHED() << "Renderer sent too many characters in title.";
@@ -1669,7 +1677,7 @@ void RenderViewHostImpl::OnDidChangeScrollOffsetPinningForMainFrame(
void RenderViewHostImpl::OnDidChangeNumWheelEvents(int count) {
}
-void RenderViewHostImpl::OnSelectionChanged(const string16& text,
+void RenderViewHostImpl::OnSelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
if (view_)
@@ -1695,8 +1703,8 @@ void RenderViewHostImpl::OnRouteMessageEvent(
}
void RenderViewHostImpl::OnRunJavaScriptMessage(
- const string16& message,
- const string16& default_prompt,
+ const base::string16& message,
+ const base::string16& default_prompt,
const GURL& frame_url,
JavaScriptMessageType type,
IPC::Message* reply_msg) {
@@ -1710,7 +1718,7 @@ void RenderViewHostImpl::OnRunJavaScriptMessage(
}
void RenderViewHostImpl::OnRunBeforeUnloadConfirm(const GURL& frame_url,
- const string16& message,
+ const base::string16& message,
bool is_reload,
IPC::Message* reply_msg) {
// While a JS before unload dialog is showing, tabs in the same process
@@ -1789,9 +1797,9 @@ void RenderViewHostImpl::OnFocusedNodeChanged(bool is_editable_node) {
void RenderViewHostImpl::OnAddMessageToConsole(
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
if (delegate_->AddMessageToConsole(level, message, line_no, source_id))
return;
@@ -2076,12 +2084,12 @@ void RenderViewHostImpl::ReloadFrame() {
}
void RenderViewHostImpl::Find(int request_id,
- const string16& search_text,
+ const base::string16& search_text,
const blink::WebFindOptions& options) {
Send(new ViewMsg_Find(GetRoutingID(), request_id, search_text, options));
}
-void RenderViewHostImpl::InsertCSS(const string16& frame_xpath,
+void RenderViewHostImpl::InsertCSS(const base::string16& frame_xpath,
const std::string& css) {
Send(new ViewMsg_CSSInsertRequest(GetRoutingID(), frame_xpath, css));
}
@@ -2203,15 +2211,6 @@ void RenderViewHostImpl::OnRequestDesktopNotificationPermission(
void RenderViewHostImpl::OnShowDesktopNotification(
const ShowDesktopNotificationHostMsgParams& params) {
- // Disallow HTML notifications from javascript: and file: schemes as this
- // allows unwanted cross-domain access.
- GURL url = params.contents_url;
- if (params.is_html &&
- (url.SchemeIs(kJavaScriptScheme) ||
- url.SchemeIs(chrome::kFileScheme))) {
- return;
- }
-
GetContentClient()->browser()->ShowDesktopNotification(
params, GetProcess()->GetID(), GetRoutingID(), false);
}
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 424a787ffa..44851eea0e 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -61,6 +61,7 @@ namespace content {
class BrowserMediaPlayerManager;
class ChildProcessSecurityPolicyImpl;
class PageState;
+class RenderFrameHostDelegate;
class RenderFrameHostImpl;
class RenderWidgetHostDelegate;
class SessionStorageNamespace;
@@ -118,6 +119,7 @@ class CONTENT_EXPORT RenderViewHostImpl
RenderViewHostImpl(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
+ RenderFrameHostDelegate* frame_delegate,
RenderWidgetHostDelegate* widget_delegate,
int routing_id,
int main_frame_routing_id,
@@ -133,8 +135,9 @@ class CONTENT_EXPORT RenderViewHostImpl
virtual void DesktopNotificationPermissionRequestDone(
int callback_context) OVERRIDE;
virtual void DesktopNotificationPostDisplay(int callback_context) OVERRIDE;
- virtual void DesktopNotificationPostError(int notification_id,
- const string16& message) OVERRIDE;
+ virtual void DesktopNotificationPostError(
+ int notification_id,
+ const base::string16& message) OVERRIDE;
virtual void DesktopNotificationPostClose(int notification_id,
bool by_user) OVERRIDE;
virtual void DesktopNotificationPostClick(int notification_id) OVERRIDE;
@@ -172,17 +175,18 @@ class CONTENT_EXPORT RenderViewHostImpl
virtual void ExecuteMediaPlayerActionAtLocation(
const gfx::Point& location,
const blink::WebMediaPlayerAction& action) OVERRIDE;
- virtual void ExecuteJavascriptInWebFrame(const string16& frame_xpath,
- const string16& jscript) OVERRIDE;
+ virtual void ExecuteJavascriptInWebFrame(
+ const base::string16& frame_xpath,
+ const base::string16& jscript) OVERRIDE;
virtual void ExecuteJavascriptInWebFrameCallbackResult(
- const string16& frame_xpath,
- const string16& jscript,
+ const base::string16& frame_xpath,
+ const base::string16& jscript,
const JavascriptResultCallback& callback) OVERRIDE;
virtual void ExecutePluginActionAtLocation(
const gfx::Point& location,
const blink::WebPluginAction& action) OVERRIDE;
virtual void ExitFullscreen() OVERRIDE;
- virtual void Find(int request_id, const string16& search_text,
+ virtual void Find(int request_id, const base::string16& search_text,
const blink::WebFindOptions& options) OVERRIDE;
virtual void StopFinding(StopFindAction action) OVERRIDE;
virtual void FirePageBeforeUnload(bool for_cross_site_transition) OVERRIDE;
@@ -192,7 +196,7 @@ class CONTENT_EXPORT RenderViewHostImpl
virtual RenderViewHostDelegate* GetDelegate() const OVERRIDE;
virtual int GetEnabledBindings() const OVERRIDE;
virtual SiteInstance* GetSiteInstance() const OVERRIDE;
- virtual void InsertCSS(const string16& frame_xpath,
+ virtual void InsertCSS(const base::string16& frame_xpath,
const std::string& css) OVERRIDE;
virtual bool IsRenderViewLive() const OVERRIDE;
virtual bool IsSubframe() const OVERRIDE;
@@ -233,7 +237,7 @@ class CONTENT_EXPORT RenderViewHostImpl
// The |opener_route_id| parameter indicates which RenderView created this
// (MSG_ROUTING_NONE if none). If |max_page_id| is larger than -1, the
// RenderView is told to start issuing page IDs at |max_page_id| + 1.
- virtual bool CreateRenderView(const string16& frame_name,
+ virtual bool CreateRenderView(const base::string16& frame_name,
int opener_route_id,
int32 max_page_id);
@@ -348,7 +352,7 @@ class CONTENT_EXPORT RenderViewHostImpl
// closed by the user.
void JavaScriptDialogClosed(IPC::Message* reply_msg,
bool success,
- const string16& user_input);
+ const base::string16& user_input);
// Tells the renderer view to focus the first (last if reverse is true) node.
void SetInitialFocus(bool reverse);
@@ -534,7 +538,7 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnNavigate(const IPC::Message& msg);
void OnUpdateState(int32 page_id, const PageState& state);
void OnUpdateTitle(int32 page_id,
- const string16& title,
+ const base::string16& title,
blink::WebTextDirection title_direction);
void OnUpdateEncoding(const std::string& encoding);
void OnUpdateTargetURL(int32 page_id, const GURL& url);
@@ -556,7 +560,7 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnDidChangeScrollOffsetPinningForMainFrame(bool is_pinned_to_left,
bool is_pinned_to_right);
void OnDidChangeNumWheelEvents(int count);
- void OnSelectionChanged(const string16& text,
+ void OnSelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range);
void OnSelectionBoundsChanged(
@@ -564,13 +568,13 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnPasteFromSelectionClipboard();
void OnRouteCloseEvent();
void OnRouteMessageEvent(const ViewMsg_PostMessage_Params& params);
- void OnRunJavaScriptMessage(const string16& message,
- const string16& default_prompt,
+ void OnRunJavaScriptMessage(const base::string16& message,
+ const base::string16& default_prompt,
const GURL& frame_url,
JavaScriptMessageType type,
IPC::Message* reply_msg);
void OnRunBeforeUnloadConfirm(const GURL& frame_url,
- const string16& message,
+ const base::string16& message,
bool is_reload,
IPC::Message* reply_msg);
void OnStartDragging(const DropData& drop_data,
@@ -583,9 +587,9 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnTakeFocus(bool reverse);
void OnFocusedNodeChanged(bool is_editable_node);
void OnAddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id);
+ const base::string16& source_id);
void OnUpdateInspectorSetting(const std::string& key,
const std::string& value);
void OnShouldCloseACK(
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc
index 67e08d2838..e81e67fc34 100644
--- a/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -5,7 +5,6 @@
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_view_host_delegate_view.h"
@@ -16,6 +15,7 @@
#include "content/public/common/url_constants.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/test/test_content_browser_client.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "net/base/net_util.h"
#include "third_party/WebKit/public/web/WebDragOperation.h"
@@ -199,7 +199,7 @@ TEST_F(RenderViewHostTest, DragEnteredFileURLsStillBlocked) {
GURL sensitive_file_url = net::FilePathToFileURL(sensitive_file_path);
dropped_data.url = highlighted_file_url;
dropped_data.filenames.push_back(DropData::FileInfo(
- UTF8ToUTF16(dragged_file_path.AsUTF8Unsafe()), string16()));
+ UTF8ToUTF16(dragged_file_path.AsUTF8Unsafe()), base::string16()));
rvh()->DragTargetDragEnter(dropped_data, client_point, screen_point,
blink::WebDragOperationNone, 0);
diff --git a/content/browser/renderer_host/render_widget_helper.cc b/content/browser/renderer_host/render_widget_helper.cc
index 7f772e382b..10e4e0ffa1 100644
--- a/content/browser/renderer_host/render_widget_helper.cc
+++ b/content/browser/renderer_host/render_widget_helper.cc
@@ -381,7 +381,7 @@ void RenderWidgetHelper::FreeTransportDIB(TransportDIB::Id dib_id) {
i = allocated_dibs_.find(dib_id);
if (i != allocated_dibs_.end()) {
- if (HANDLE_EINTR(close(i->second)) < 0)
+ if (IGNORE_EINTR(close(i->second)) < 0)
PLOG(ERROR) << "close";
allocated_dibs_.erase(i);
} else {
@@ -392,7 +392,7 @@ void RenderWidgetHelper::FreeTransportDIB(TransportDIB::Id dib_id) {
void RenderWidgetHelper::ClearAllocatedDIBs() {
for (std::map<TransportDIB::Id, int>::iterator
i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) {
- if (HANDLE_EINTR(close(i->second)) < 0)
+ if (IGNORE_EINTR(close(i->second)) < 0)
PLOG(ERROR) << "close: " << i->first;
}
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc
index bfdf6a5450..f9b3fd3519 100644
--- a/content/browser/renderer_host/render_widget_host_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -47,7 +47,8 @@ class RenderWidgetHostBrowserTest : public ContentBrowserTest {
};
// Disabled on Windows and CrOS because it is flaky: crbug.com/272379.
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+// Disabled on Ozone due to flake: crbug.com/315392.
+#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(USE_OZONE)
#define MAYBE_GetSnapshotFromRendererTest DISABLED_GetSnapshotFromRendererTest
#else
#define MAYBE_GetSnapshotFromRendererTest GetSnapshotFromRendererTest
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 67b3b1f228..78edc465cf 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -30,10 +30,11 @@
#include "content/browser/renderer_host/backing_store.h"
#include "content/browser/renderer_host/backing_store_manager.h"
#include "content/browser/renderer_host/dip_util.h"
-#include "content/browser/renderer_host/input/immediate_input_router.h"
+#include "content/browser/renderer_host/input/input_router_impl.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "content/browser/renderer_host/input/timeout_monitor.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -212,9 +213,10 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
is_threaded_compositing_enabled_ = IsThreadedCompositingEnabled();
-
- g_routing_id_widget_map.Get().insert(std::make_pair(
- RenderWidgetHostID(process->GetID(), routing_id_), this));
+ std::pair<RoutingIDWidgetMap::iterator, bool> result =
+ g_routing_id_widget_map.Get().insert(std::make_pair(
+ RenderWidgetHostID(process->GetID(), routing_id_), this));
+ CHECK(result.second) << "Inserting a duplicate item!";
process_->AddRoute(routing_id_, this);
// If we're initially visible, tell the process host that we're alive.
@@ -225,14 +227,20 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
accessibility_mode_ =
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode();
- input_router_.reset(
- new ImmediateInputRouter(process_, this, this, routing_id_));
+ input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
#if defined(USE_AURA)
bool overscroll_enabled = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0";
SetOverscrollControllerEnabled(overscroll_enabled);
#endif
+
+ if (GetProcess()->IsGuest() || !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableHangMonitor)) {
+ hang_monitor_timeout_.reset(new TimeoutMonitor(
+ base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive,
+ weak_factory_.GetWeakPtr())));
+ }
}
RenderWidgetHostImpl::~RenderWidgetHostImpl() {
@@ -897,53 +905,21 @@ bool RenderWidgetHostImpl::ScheduleComposite() {
return true;
}
-void RenderWidgetHostImpl::StartHangMonitorTimeout(TimeDelta delay) {
- if (!GetProcess()->IsGuest() && CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableHangMonitor)) {
- return;
- }
-
- // Set time_when_considered_hung_ if it's null. Also, update
- // time_when_considered_hung_ if the caller's request is sooner than the
- // existing one. This will have the side effect that the existing timeout will
- // be forgotten.
- Time requested_end_time = Time::Now() + delay;
- if (time_when_considered_hung_.is_null() ||
- time_when_considered_hung_ > requested_end_time)
- time_when_considered_hung_ = requested_end_time;
-
- // If we already have a timer with the same or shorter duration, then we can
- // wait for it to finish.
- if (hung_renderer_timer_.IsRunning() &&
- hung_renderer_timer_.GetCurrentDelay() <= delay) {
- // If time_when_considered_hung_ was null, this timer may fire early.
- // CheckRendererIsUnresponsive handles that by calling
- // StartHangMonitorTimeout with the remaining time.
- // If time_when_considered_hung_ was non-null, it means we still haven't
- // heard from the renderer so we leave time_when_considered_hung_ as is.
- return;
- }
-
- // Either the timer is not yet running, or we need to adjust the timer to
- // fire sooner.
- time_when_considered_hung_ = requested_end_time;
- hung_renderer_timer_.Stop();
- hung_renderer_timer_.Start(FROM_HERE, delay, this,
- &RenderWidgetHostImpl::CheckRendererIsUnresponsive);
+void RenderWidgetHostImpl::StartHangMonitorTimeout(base::TimeDelta delay) {
+ if (hang_monitor_timeout_)
+ hang_monitor_timeout_->Start(delay);
}
void RenderWidgetHostImpl::RestartHangMonitorTimeout() {
- // Setting to null will cause StartHangMonitorTimeout to restart the timer.
- time_when_considered_hung_ = Time();
- StartHangMonitorTimeout(
- TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
+ if (hang_monitor_timeout_)
+ hang_monitor_timeout_->Restart(
+ base::TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
}
void RenderWidgetHostImpl::StopHangMonitorTimeout() {
- time_when_considered_hung_ = Time();
+ if (hang_monitor_timeout_)
+ hang_monitor_timeout_->Stop();
RendererIsResponsive();
- // We do not bother to stop the hung_renderer_timer_ here in case it will be
- // started again shortly, which happens to be the common use case.
}
void RenderWidgetHostImpl::EnableFullAccessibilityMode() {
@@ -1256,8 +1232,7 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
waiting_for_screen_rects_ack_ = false;
// Reset to ensure that input routing works with a new renderer.
- input_router_.reset(
- new ImmediateInputRouter(process_, this, this, routing_id_));
+ input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
if (overscroll_controller_)
overscroll_controller_->Reset();
@@ -1310,8 +1285,20 @@ void RenderWidgetHostImpl::SetInputMethodActive(bool activate) {
Send(new ViewMsg_SetInputMethodActive(GetRoutingID(), activate));
}
+void RenderWidgetHostImpl::CandidateWindowShown() {
+ Send(new ViewMsg_CandidateWindowShown(GetRoutingID()));
+}
+
+void RenderWidgetHostImpl::CandidateWindowUpdated() {
+ Send(new ViewMsg_CandidateWindowUpdated(GetRoutingID()));
+}
+
+void RenderWidgetHostImpl::CandidateWindowHidden() {
+ Send(new ViewMsg_CandidateWindowHidden(GetRoutingID()));
+}
+
void RenderWidgetHostImpl::ImeSetComposition(
- const string16& text,
+ const base::string16& text,
const std::vector<blink::WebCompositionUnderline>& underlines,
int selection_start,
int selection_end) {
@@ -1320,7 +1307,7 @@ void RenderWidgetHostImpl::ImeSetComposition(
}
void RenderWidgetHostImpl::ImeConfirmComposition(
- const string16& text,
+ const base::string16& text,
const gfx::Range& replacement_range,
bool keep_selection) {
Send(new ViewMsg_ImeConfirmComposition(
@@ -1328,7 +1315,7 @@ void RenderWidgetHostImpl::ImeConfirmComposition(
}
void RenderWidgetHostImpl::ImeCancelComposition() {
- Send(new ViewMsg_ImeSetComposition(GetRoutingID(), string16(),
+ Send(new ViewMsg_ImeSetComposition(GetRoutingID(), base::string16(),
std::vector<blink::WebCompositionUnderline>(), 0, 0));
}
@@ -1387,19 +1374,7 @@ void RenderWidgetHostImpl::Destroy() {
delete this;
}
-void RenderWidgetHostImpl::CheckRendererIsUnresponsive() {
- // If we received a call to StopHangMonitorTimeout.
- if (time_when_considered_hung_.is_null())
- return;
-
- // If we have not waited long enough, then wait some more.
- Time now = Time::Now();
- if (now < time_when_considered_hung_) {
- StartHangMonitorTimeout(time_when_considered_hung_ - now);
- return;
- }
-
- // OK, looks like we have a hung renderer!
+void RenderWidgetHostImpl::RendererIsUnresponsive() {
NotificationService::current()->Notify(
NOTIFICATION_RENDER_WIDGET_HOST_HANG,
Source<RenderWidgetHost>(this),
@@ -1432,7 +1407,7 @@ void RenderWidgetHostImpl::OnClose() {
}
void RenderWidgetHostImpl::OnSetTooltipText(
- const string16& tooltip_text,
+ const base::string16& tooltip_text,
WebTextDirection text_direction_hint) {
// First, add directionality marks around tooltip text if necessary.
// A naive solution would be to simply always wrap the text. However, on
@@ -1447,7 +1422,7 @@ void RenderWidgetHostImpl::OnSetTooltipText(
// trying to detect the directionality from the tooltip text rather than the
// element direction. One could argue that would be a preferable solution
// but we use the current approach to match Fx & IE's behavior.
- string16 wrapped_tooltip_text = tooltip_text;
+ base::string16 wrapped_tooltip_text = tooltip_text;
if (!tooltip_text.empty()) {
if (text_direction_hint == blink::WebTextDirectionLeftToRight) {
// Force the tooltip to have LTR directionality.
@@ -1526,6 +1501,13 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame(
uint32 output_surface_id = param.a;
param.b.AssignTo(frame.get());
+ bool fixed_page_scale =
+ frame->metadata.min_page_scale_factor ==
+ frame->metadata.max_page_scale_factor;
+ int updated_view_flags = fixed_page_scale ? InputRouter::FIXED_PAGE_SCALE
+ : InputRouter::VIEW_FLAGS_NONE;
+ input_router_->OnViewUpdated(updated_view_flags);
+
if (view_) {
view_->OnSwapCompositorFrame(output_surface_id, frame.Pass());
view_->DidReceiveRendererFrame();
@@ -1925,11 +1907,11 @@ void RenderWidgetHostImpl::ScrollBackingStoreRect(const gfx::Vector2d& delta,
backing_store->ScrollBackingStore(delta, clip_rect, view_size);
}
-void RenderWidgetHostImpl::Replace(const string16& word) {
+void RenderWidgetHostImpl::Replace(const base::string16& word) {
Send(new InputMsg_Replace(routing_id_, word));
}
-void RenderWidgetHostImpl::ReplaceMisspelling(const string16& word) {
+void RenderWidgetHostImpl::ReplaceMisspelling(const base::string16& word) {
Send(new InputMsg_ReplaceMisspelling(routing_id_, word));
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 36a63e3d41..d1231cac59 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -83,6 +83,7 @@ class OverscrollController;
class RenderWidgetHostDelegate;
class RenderWidgetHostViewPort;
class SyntheticGestureController;
+class TimeoutMonitor;
struct EditCommand;
// This implements the RenderWidgetHost interface that is exposed to
@@ -164,8 +165,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
int tag,
const gfx::Size& page_size,
const gfx::Size& desired_size) OVERRIDE;
- virtual void Replace(const string16& word) OVERRIDE;
- virtual void ReplaceMisspelling(const string16& word) OVERRIDE;
+ virtual void Replace(const base::string16& word) OVERRIDE;
+ virtual void ReplaceMisspelling(const base::string16& word) OVERRIDE;
virtual void ResizeRectChanged(const gfx::Rect& new_rect) OVERRIDE;
virtual void RestartHangMonitorTimeout() OVERRIDE;
virtual void SetIgnoreInputEvents(bool ignore_input_events) OVERRIDE;
@@ -312,6 +313,11 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// display input method windows under the cursor.)
void SetInputMethodActive(bool activate);
+ // Notifies the renderer changes of IME candidate window state.
+ void CandidateWindowShown();
+ void CandidateWindowUpdated();
+ void CandidateWindowHidden();
+
// Update the composition node of the renderer (or WebKit).
// WebKit has a special node (a composition node) for input method to change
// its text without affecting any other DOM nodes. When the input method
@@ -328,7 +334,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// * when it receives a "preedit_changed" signal of GtkIMContext (on Linux);
// * when markedText of NSTextInput is called (on Mac).
void ImeSetComposition(
- const string16& text,
+ const base::string16& text,
const std::vector<blink::WebCompositionUnderline>& underlines,
int selection_start,
int selection_end);
@@ -339,7 +345,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// (on Windows);
// * when it receives a "commit" signal of GtkIMContext (on Linux);
// * when insertText of NSTextInput is called (on Mac).
- void ImeConfirmComposition(const string16& text,
+ void ImeConfirmComposition(const base::string16& text,
const gfx::Range& replacement_range,
bool keep_selection);
@@ -631,9 +637,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// Tell this object to destroy itself.
void Destroy();
- // Checks whether the renderer is hung and calls NotifyRendererUnresponsive
- // if it is.
- void CheckRendererIsUnresponsive();
+ // Called by |hang_timeout_monitor_| on delayed response from the renderer.
+ void RendererIsUnresponsive();
// Called if we know the renderer is responsive. When we currently think the
// renderer is unresponsive, this will clear that state and call
@@ -646,7 +651,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
void OnClose();
void OnUpdateScreenRectsAck();
void OnRequestMove(const gfx::Rect& pos);
- void OnSetTooltipText(const string16& tooltip_text,
+ void OnSetTooltipText(const base::string16& tooltip_text,
blink::WebTextDirection text_direction_hint);
void OnPaintAtSizeAck(int tag, const gfx::Size& size);
#if defined(OS_MACOSX)
@@ -905,6 +910,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
scoped_ptr<OverscrollController> overscroll_controller_;
+ scoped_ptr<TimeoutMonitor> hang_monitor_timeout_;
+
#if defined(OS_WIN)
std::list<HWND> dummy_windows_for_activation_;
#endif
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index f1edc910ae..967c814271 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -10,15 +10,14 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/backing_store.h"
#include "content/browser/renderer_host/input/gesture_event_filter.h"
-#include "content/browser/renderer_host/input/immediate_input_router.h"
-#include "content/browser/renderer_host/input/synthetic_web_input_event_builders.h"
+#include "content/browser/renderer_host/input/input_router_impl.h"
#include "content/browser/renderer_host/input/tap_suppression_controller.h"
#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_port.h"
@@ -29,6 +28,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
@@ -48,6 +48,7 @@
using base::TimeDelta;
using blink::WebGestureEvent;
using blink::WebInputEvent;
+using blink::WebKeyboardEvent;
using blink::WebMouseWheelEvent;
using blink::WebTouchEvent;
using blink::WebTouchPoint;
@@ -165,6 +166,7 @@ class MockInputRouter : public InputRouter {
return NULL;
}
virtual bool ShouldForwardTouchEvent() const OVERRIDE { return true; }
+ virtual void OnViewUpdated(int view_flags) OVERRIDE {}
// IPC::Listener
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
@@ -197,8 +199,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
int routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id, false),
unresponsive_timer_fired_(false) {
- immediate_input_router_ =
- static_cast<ImmediateInputRouter*>(input_router_.get());
+ input_router_impl_ = static_cast<InputRouterImpl*>(input_router_.get());
}
// Allow poking at a few private members.
@@ -258,11 +259,12 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
void DisableGestureDebounce() {
- gesture_event_filter()->debounce_enabled_ = false;
+ gesture_event_filter()->set_debounce_enabled_for_testing(false);
}
void set_debounce_interval_time_ms(int delay_ms) {
- gesture_event_filter()->debounce_interval_time_ms_ = delay_ms;
+ gesture_event_filter()->
+ set_debounce_interval_time_ms_for_testing(delay_ms);
}
bool TouchEventQueueEmpty() const {
@@ -316,24 +318,24 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
const TouchEventQueue* touch_event_queue() const {
- return immediate_input_router_->touch_event_queue_.get();
+ return input_router_impl_->touch_event_queue_.get();
}
const GestureEventFilter* gesture_event_filter() const {
- return immediate_input_router_->gesture_event_filter_.get();
+ return input_router_impl_->gesture_event_filter_.get();
}
GestureEventFilter* gesture_event_filter() {
- return immediate_input_router_->gesture_event_filter_.get();
+ return input_router_impl_->gesture_event_filter_.get();
}
private:
bool unresponsive_timer_fired_;
- // |immediate_input_router_| and |mock_input_router_| are owned by
- // RenderWidgetHostImpl |input_router_|. Below are provided for convenience so
+ // |input_router_impl_| and |mock_input_router_| are owned by
+ // RenderWidgetHostImpl. The handles below are provided for convenience so
// that we don't have to reinterpret_cast it all the time.
- ImmediateInputRouter* immediate_input_router_;
+ InputRouterImpl* input_router_impl_;
MockInputRouter* mock_input_router_;
scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
@@ -651,7 +653,10 @@ class RenderWidgetHostTest : public testing::Test {
}
void SimulateKeyboardEvent(WebInputEvent::Type type) {
- host_->ForwardKeyboardEvent(SyntheticWebKeyboardEventBuilder::Build(type));
+ WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
+ NativeWebKeyboardEvent native_event;
+ memcpy(&native_event, &event, sizeof(event));
+ host_->ForwardKeyboardEvent(native_event);
}
void SimulateMouseEvent(WebInputEvent::Type type) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index a4815046d5..171bacf9b4 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -14,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/worker_pool.h"
+#include "cc/base/latency_info_swap_promise.h"
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_renderer_layer.h"
#include "cc/layers/layer.h"
@@ -28,6 +29,7 @@
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/browser/android/overscroll_glow.h"
+#include "content/browser/devtools/render_view_devtools_agent_host.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
@@ -40,11 +42,14 @@
#include "content/common/gpu/gpu_messages.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "skia/ext/image_operations.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/base/android/window_android.h"
#include "ui/gfx/android/device_display_info.h"
#include "ui/gfx/android/java_bitmap.h"
@@ -111,7 +116,10 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
texture_id_in_layer_(0),
last_output_surface_id_(kUndefinedOutputSurfaceId),
weak_ptr_factory_(this),
- overscroll_effect_enabled_(true),
+ overscroll_effect_enabled_(
+ !CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kDisableOverscrollEdgeEffect)),
+ overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
flush_input_requested_(false),
accelerated_surface_route_id_(0),
using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
@@ -122,16 +130,6 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
layer_ = texture_layer_;
}
- overscroll_effect_enabled_ = !CommandLine::ForCurrentProcess()->
- HasSwitch(switches::kDisableOverscrollEdgeEffect);
- // Don't block the main thread with effect resource loading.
- // Actual effect creation is deferred until an overscroll event is received.
- if (overscroll_effect_enabled_) {
- base::WorkerPool::PostTask(FROM_HERE,
- base::Bind(&OverscrollGlow::EnsureResources),
- true);
- }
-
host_->SetView(this);
SetContentViewCore(content_view_core);
ImageTransportFactoryAndroid::AddObserver(this);
@@ -332,16 +330,15 @@ void RenderWidgetHostViewAndroid::Focus() {
host_->Focus();
host_->SetInputMethodActive(true);
ResetClipping();
- if (overscroll_effect_)
- overscroll_effect_->SetEnabled(true);
+ if (overscroll_effect_enabled_)
+ overscroll_effect_->Enable();
}
void RenderWidgetHostViewAndroid::Blur() {
host_->ExecuteEditCommand("Unselect", "");
host_->SetInputMethodActive(false);
host_->Blur();
- if (overscroll_effect_)
- overscroll_effect_->SetEnabled(false);
+ overscroll_effect_->Disable();
}
bool RenderWidgetHostViewAndroid::HasFocus() const {
@@ -523,11 +520,11 @@ void RenderWidgetHostViewAndroid::Destroy() {
}
void RenderWidgetHostViewAndroid::SetTooltipText(
- const string16& tooltip_text) {
+ const base::string16& tooltip_text) {
// Tooltips don't makes sense on Android.
}
-void RenderWidgetHostViewAndroid::SelectionChanged(const string16& text,
+void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
@@ -573,7 +570,7 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback) {
- if (!IsSurfaceAvailableForCopy()) {
+ if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
callback.Run(false, SkBitmap());
return;
}
@@ -589,6 +586,11 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
gfx::Rect src_subrect_in_pixel =
ConvertRectToPixel(device_scale_factor, src_subrect);
+ if (using_synchronous_compositor_) {
+ SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback);
+ return;
+ }
+
scoped_ptr<cc::CopyOutputRequest> request;
if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
@@ -692,7 +694,7 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
frame_provider_ = new cc::DelegatedFrameProvider(
resource_collection_.get(), frame_data.Pass());
delegated_renderer_layer_ =
- cc::DelegatedRendererLayer::Create(NULL, frame_provider_);
+ cc::DelegatedRendererLayer::Create(frame_provider_);
layer_ = delegated_renderer_layer_;
if (are_layers_attached_)
AttachLayers();
@@ -779,8 +781,11 @@ void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
texture_size_in_layer_ = frame->gl_frame_data->size;
ComputeContentsSize(frame->metadata);
- if (layer_->layer_tree_host())
- layer_->layer_tree_host()->SetLatencyInfo(frame->metadata.latency_info);
+ if (layer_->layer_tree_host()) {
+ scoped_ptr<cc::SwapPromise> swap_promise(
+ new cc::LatencyInfoSwapPromise(frame->metadata.latency_info));
+ layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
+ }
BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
}
@@ -791,6 +796,44 @@ void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
// compositor flow.
UpdateContentViewCoreFrameMetadata(frame_metadata);
ComputeContentsSize(frame_metadata);
+
+ // DevTools ScreenCast support for Android WebView.
+ if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
+ scoped_refptr<DevToolsAgentHost> dtah =
+ DevToolsAgentHost::GetOrCreateFor(
+ RenderViewHost::From(GetRenderWidgetHost()));
+ // Unblock the compositor.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
+ static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
+ frame_metadata));
+ }
+}
+
+void RenderWidgetHostViewAndroid::SynchronousCopyContents(
+ const gfx::Rect& src_subrect_in_pixel,
+ const gfx::Size& dst_size_in_pixel,
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
+ SynchronousCompositor* compositor =
+ SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
+ host_->GetRoutingID());
+ if (!compositor) {
+ callback.Run(false, SkBitmap());
+ return;
+ }
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ dst_size_in_pixel.width(),
+ dst_size_in_pixel.height());
+ bitmap.allocPixels();
+ SkCanvas canvas(bitmap);
+ canvas.scale(
+ (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
+ (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
+ compositor->DemandDrawSw(&canvas);
+ callback.Run(true, bitmap);
}
void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
@@ -856,6 +899,8 @@ void RenderWidgetHostViewAndroid::AttachLayers() {
return;
content_view_core_->AttachLayer(layer_);
+ if (overscroll_effect_enabled_)
+ overscroll_effect_->Enable();
}
void RenderWidgetHostViewAndroid::RemoveLayers() {
@@ -864,38 +909,16 @@ void RenderWidgetHostViewAndroid::RemoveLayers() {
if (!layer_.get())
return;
- if (overscroll_effect_)
- content_view_core_->RemoveLayer(overscroll_effect_->root_layer());
-
content_view_core_->RemoveLayer(layer_);
+ overscroll_effect_->Disable();
}
bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
- if (!overscroll_effect_)
- return false;
-
- bool overscroll_running = overscroll_effect_->Animate(frame_time);
- if (!overscroll_running)
- content_view_core_->RemoveLayer(overscroll_effect_->root_layer());
-
- return overscroll_running;
-}
-
-void RenderWidgetHostViewAndroid::CreateOverscrollEffectIfNecessary() {
- if (!overscroll_effect_enabled_ || overscroll_effect_)
- return;
-
- overscroll_effect_ = OverscrollGlow::Create(true, content_size_in_layer_);
-
- // Prevent future creation attempts on failure.
- if (!overscroll_effect_)
- overscroll_effect_enabled_ = false;
+ return overscroll_effect_->Animate(frame_time);
}
void RenderWidgetHostViewAndroid::UpdateAnimationSize(
const cc::CompositorFrameMetadata& frame_metadata) {
- if (!overscroll_effect_)
- return;
// Disable edge effects for axes on which scrolling is impossible.
gfx::SizeF ceiled_viewport_size =
gfx::ToCeiledSize(frame_metadata.viewport_size);
@@ -906,19 +929,6 @@ void RenderWidgetHostViewAndroid::UpdateAnimationSize(
overscroll_effect_->set_size(content_size_in_layer_);
}
-void RenderWidgetHostViewAndroid::ScheduleAnimationIfNecessary() {
- if (!content_view_core_ || !overscroll_effect_)
- return;
-
- if (overscroll_effect_->NeedsAnimate() && are_layers_attached_) {
- if (!overscroll_effect_->root_layer()->parent())
- content_view_core_->AttachLayer(overscroll_effect_->root_layer());
- content_view_core_->SetNeedsAnimate();
- } else {
- content_view_core_->RemoveLayer(overscroll_effect_->root_layer());
- }
-}
-
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
@@ -1143,8 +1153,8 @@ void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
void RenderWidgetHostViewAndroid::SendGestureEvent(
const blink::WebGestureEvent& event) {
// Sending a gesture that may trigger overscroll should resume the effect.
- if (overscroll_effect_)
- overscroll_effect_->SetEnabled(true);
+ if (overscroll_effect_enabled_)
+ overscroll_effect_->Enable();
if (host_)
host_->ForwardGestureEvent(event);
@@ -1212,14 +1222,15 @@ SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
void RenderWidgetHostViewAndroid::OnOverscrolled(
gfx::Vector2dF accumulated_overscroll,
gfx::Vector2dF current_fling_velocity) {
- CreateOverscrollEffectIfNecessary();
- if (!overscroll_effect_)
+ if (!content_view_core_ || !are_layers_attached_)
return;
- overscroll_effect_->OnOverscrolled(base::TimeTicks::Now(),
- accumulated_overscroll,
- current_fling_velocity);
- ScheduleAnimationIfNecessary();
+ if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
+ base::TimeTicks::Now(),
+ accumulated_overscroll,
+ current_fling_velocity)) {
+ content_view_core_->SetNeedsAnimate();
+ }
}
void RenderWidgetHostViewAndroid::SetContentViewCore(
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index c01120ffa9..db1bc5523e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -15,7 +15,6 @@
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "cc/layers/delegated_frame_resource_collection.h"
-#include "cc/layers/delegated_renderer_layer_client.h"
#include "cc/layers/texture_layer_client.h"
#include "cc/output/begin_frame_args.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -112,8 +111,8 @@ class RenderWidgetHostViewAndroid
virtual void RenderProcessGone(base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SelectionBoundsChanged(
@@ -257,9 +256,7 @@ class RenderWidgetHostViewAndroid
void AttachLayers();
void RemoveLayers();
- void CreateOverscrollEffectIfNecessary();
void UpdateAnimationSize(const cc::CompositorFrameMetadata& frame_metadata);
- void ScheduleAnimationIfNecessary();
// Called after async screenshot task completes. Scales and crops the result
// of the copy.
@@ -272,6 +269,12 @@ class RenderWidgetHostViewAndroid
const base::Callback<void(bool, const SkBitmap&)>& callback,
scoped_ptr<cc::CopyOutputResult> result);
+ // DevTools ScreenCast support for Android WebView.
+ void SynchronousCopyContents(
+ const gfx::Rect& src_subrect_in_pixel,
+ const gfx::Size& dst_size_in_pixel,
+ const base::Callback<void(bool, const SkBitmap&)>& callback);
+
// The model object.
RenderWidgetHostImpl* host_;
@@ -323,8 +326,9 @@ class RenderWidgetHostViewAndroid
std::queue<base::Closure> ack_callbacks_;
+ const bool overscroll_effect_enabled_;
// Used to render overscroll overlays.
- bool overscroll_effect_enabled_;
+ // Note: |overscroll_effect_| will never be NULL, even if it's never enabled.
scoped_ptr<OverscrollGlow> overscroll_effect_;
bool flush_input_requested_;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 81bea27603..7b1bdf55be 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "base/auto_reset.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
@@ -450,6 +451,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
: host_(RenderWidgetHostImpl::From(host)),
window_(new aura::Window(this)),
in_shutdown_(false),
+ in_bounds_changed_(false),
is_fullscreen_(false),
popup_parent_host_view_(NULL),
popup_child_host_view_(NULL),
@@ -990,7 +992,8 @@ void RenderWidgetHostViewAura::Destroy() {
delete window_;
}
-void RenderWidgetHostViewAura::SetTooltipText(const string16& tooltip_text) {
+void RenderWidgetHostViewAura::SetTooltipText(
+ const base::string16& tooltip_text) {
tooltip_ = tooltip_text;
aura::Window* root_window = window_->GetRootWindow();
aura::client::TooltipClient* tooltip_client =
@@ -1002,7 +1005,7 @@ void RenderWidgetHostViewAura::SetTooltipText(const string16& tooltip_text) {
}
}
-void RenderWidgetHostViewAura::SelectionChanged(const string16& text,
+void RenderWidgetHostViewAura::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
@@ -1082,16 +1085,33 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
return;
}
+ // Try get a texture to reuse.
+ scoped_refptr<OwnedMailbox> subscriber_texture;
+ if (frame_subscriber_) {
+ if (!idle_frame_subscriber_textures_.empty()) {
+ subscriber_texture = idle_frame_subscriber_textures_.back();
+ idle_frame_subscriber_textures_.pop_back();
+ } else if (GLHelper* helper =
+ ImageTransportFactory::GetInstance()->GetGLHelper()) {
+ subscriber_texture = new OwnedMailbox(helper);
+ }
+ }
+
scoped_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateRequest(base::Bind(
&RenderWidgetHostViewAura::
- CopyFromCompositingSurfaceHasResultForVideo,
+ CopyFromCompositingSurfaceHasResultForVideo,
AsWeakPtr(), // For caching the ReadbackYUVInterface on this class.
+ subscriber_texture,
target,
callback));
gfx::Rect src_subrect_in_pixel =
ConvertRectToPixel(current_device_scale_factor_, src_subrect);
request->set_area(src_subrect_in_pixel);
+ if (subscriber_texture) {
+ request->SetTextureMailbox(cc::TextureMailbox(
+ subscriber_texture->mailbox(), subscriber_texture->sync_point()));
+ }
window_->layer()->RequestCopyOfOutput(request.Pass());
}
@@ -1115,10 +1135,10 @@ void RenderWidgetHostViewAura::BeginFrameSubscription(
}
void RenderWidgetHostViewAura::EndFrameSubscription() {
+ idle_frame_subscriber_textures_.clear();
frame_subscriber_.reset();
}
-
void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
// Delay processing the state change until we either get a software frame if
// switching to software mode or receive a buffers swapped notification
@@ -1148,7 +1168,10 @@ void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
if (HasDisplayPropertyChanged(window_))
host_->InvalidateScreenInfo();
- window_->SetBounds(rect);
+ // Don't recursively call SetBounds if this bounds update is the result of
+ // a Window::SetBoundsInternal call.
+ if (!in_bounds_changed_)
+ window_->SetBounds(rect);
host_->WasResized();
MaybeCreateResizeLock();
if (touch_editing_client_) {
@@ -1405,7 +1428,13 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
resource_collection_ = new cc::DelegatedFrameResourceCollection;
resource_collection_->SetClient(this);
}
- if (!frame_provider_.get() || frame_size != frame_provider_->frame_size()) {
+ // If the physical frame size changes, we need a new |frame_provider_|. If
+ // the physical frame size is the same, but the size in DIP changed, we
+ // need to adjust the scale at which the frames will be drawn, and we do
+ // this by making a new |frame_provider_| also to ensure the scale change
+ // is presented in sync with the new frame content.
+ if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() ||
+ frame_size_in_dip != current_frame_size_) {
frame_provider_ = new cc::DelegatedFrameProvider(
resource_collection_.get(), frame_data.Pass());
window_->layer()->SetShowDelegatedContent(frame_provider_.get(),
@@ -1872,17 +1901,34 @@ void RenderWidgetHostViewAura::PrepareBitmapCopyOutputResult(
callback.Run(true, bitmap);
}
-static void CopyFromCompositingSurfaceFinishedForVideo(
+void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo(
+ base::WeakPtr<RenderWidgetHostViewAura> rwhva,
const base::Callback<void(bool)>& callback,
+ scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_ptr<cc::SingleReleaseCallback> release_callback,
bool result) {
- release_callback->Run(0, false);
callback.Run(result);
+
+ GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+ uint32 sync_point = gl_helper ? gl_helper->InsertSyncPoint() : 0;
+ if (release_callback) {
+ DCHECK(!subscriber_texture);
+ release_callback->Run(sync_point, false);
+ } else {
+ // If there's no release callback, then the texture is from
+ // idle_frame_subscriber_textures_ and we can put it back there.
+ DCHECK(subscriber_texture);
+ subscriber_texture->UpdateSyncPoint(sync_point);
+ if (rwhva && rwhva->frame_subscriber_ && subscriber_texture->texture_id())
+ rwhva->idle_frame_subscriber_textures_.push_back(subscriber_texture);
+ subscriber_texture = NULL;
+ }
}
// static
void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo(
base::WeakPtr<RenderWidgetHostViewAura> rwhva,
+ scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_refptr<media::VideoFrame> video_frame,
const base::Callback<void(bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result) {
@@ -1890,7 +1936,6 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo(
if (!rwhva)
return;
-
if (result->IsEmpty())
return;
if (result->size().IsEmpty())
@@ -1993,8 +2038,10 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo(
ignore_result(scoped_callback_runner.Release());
base::Callback<void(bool result)> finished_callback = base::Bind(
- &CopyFromCompositingSurfaceFinishedForVideo,
+ &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo,
+ rwhva->AsWeakPtr(),
callback,
+ subscriber_texture,
base::Passed(&release_callback));
yuv_readback_pipeline->ReadbackYUV(
texture_mailbox.name(),
@@ -2180,8 +2227,10 @@ void RenderWidgetHostViewAura::SetCompositionText(
}
void RenderWidgetHostViewAura::ConfirmCompositionText() {
- if (host_ && has_composition_text_)
- host_->ImeConfirmComposition(string16(), gfx::Range::InvalidRange(), false);
+ if (host_ && has_composition_text_) {
+ host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
+ false);
+ }
has_composition_text_ = false;
}
@@ -2191,7 +2240,7 @@ void RenderWidgetHostViewAura::ClearCompositionText() {
has_composition_text_ = false;
}
-void RenderWidgetHostViewAura::InsertText(const string16& text) {
+void RenderWidgetHostViewAura::InsertText(const base::string16& text) {
DCHECK(text_input_type_ != ui::TEXT_INPUT_TYPE_NONE);
if (host_)
host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
@@ -2326,7 +2375,7 @@ bool RenderWidgetHostViewAura::DeleteRange(const gfx::Range& range) {
bool RenderWidgetHostViewAura::GetTextFromRange(
const gfx::Range& range,
- string16* text) const {
+ base::string16* text) const {
gfx::Range selection_text_range(selection_text_offset_,
selection_text_offset_ + selection_text_.length());
@@ -2386,12 +2435,15 @@ void RenderWidgetHostViewAura::EnsureCaretInRect(const gfx::Rect& rect) {
}
void RenderWidgetHostViewAura::OnCandidateWindowShown() {
+ host_->CandidateWindowShown();
}
void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
+ host_->CandidateWindowUpdated();
}
void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
+ host_->CandidateWindowHidden();
}
////////////////////////////////////////////////////////////////////////////////
@@ -2428,6 +2480,7 @@ gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
+ base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
// We care about this only in fullscreen mode, where there is no
// WebContentsViewAura. We are sized via SetSize() or SetBounds() by
// WebContentsViewAura in other cases.
@@ -2976,6 +3029,17 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
(screen->GetDisplayNearestWindow(window_).id() !=
screen->GetDisplayNearestWindow(gained_focus).id());
if (is_fullscreen_ && !in_shutdown_ && !focusing_other_display) {
+#if defined(OS_WIN)
+ // On Windows, if we are switching to a non Aura Window on a different
+ // screen we should not close the fullscreen window.
+ if (!gained_focus) {
+ POINT point = {0};
+ ::GetCursorPos(&point);
+ if (screen->GetDisplayNearestWindow(window_).id() !=
+ screen->GetDisplayNearestPoint(gfx::Point(point)).id())
+ return;
+ }
+#endif
in_shutdown_ = true;
host_->Shutdown();
}
@@ -3132,6 +3196,8 @@ void RenderWidgetHostViewAura::OnLostResources() {
current_surface_ = NULL;
UpdateExternalTexture();
+ idle_frame_subscriber_textures_.clear();
+
// Make sure all ImageTransportClients are deleted now that the context those
// are using is becoming invalid. This sends pending ACKs and needs to happen
// after calling UpdateExternalTexture() which syncs with the impl thread.
@@ -3238,8 +3304,10 @@ bool RenderWidgetHostViewAura::NeedsInputGrab() {
void RenderWidgetHostViewAura::FinishImeCompositionSession() {
if (!has_composition_text_)
return;
- if (host_)
- host_->ImeConfirmComposition(string16(), gfx::Range::InvalidRange(), false);
+ if (host_) {
+ host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
+ false);
+ }
ImeCancelComposition();
}
@@ -3348,6 +3416,11 @@ void RenderWidgetHostViewAura::AddedToRootWindow() {
}
if (current_surface_.get())
UpdateExternalTexture();
+ if (HasFocus()) {
+ ui::InputMethod* input_method = GetInputMethod();
+ if (input_method)
+ input_method->SetFocusedTextInputClient(this);
+ }
}
void RenderWidgetHostViewAura::RemovingFromRootWindow() {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 385495a9c4..86db86410d 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -20,6 +20,7 @@
#include "cc/resources/texture_mailbox.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/aura/image_transport_factory.h"
+#include "content/browser/aura/owned_mailbox.h"
#include "content/browser/renderer_host/delegated_frame_evictor.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/software_frame_manager.h"
@@ -192,8 +193,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
virtual void RenderProcessGone(base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SelectionBoundsChanged(
@@ -258,7 +259,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const ui::CompositionText& composition) OVERRIDE;
virtual void ConfirmCompositionText() OVERRIDE;
virtual void ClearCompositionText() OVERRIDE;
- virtual void InsertText(const string16& text) OVERRIDE;
+ virtual void InsertText(const base::string16& text) OVERRIDE;
virtual void InsertChar(char16 ch, int flags) OVERRIDE;
virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE;
virtual ui::TextInputType GetTextInputType() const OVERRIDE;
@@ -274,7 +275,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
virtual bool SetSelectionRange(const gfx::Range& range) OVERRIDE;
virtual bool DeleteRange(const gfx::Range& range) OVERRIDE;
virtual bool GetTextFromRange(const gfx::Range& range,
- string16* text) const OVERRIDE;
+ base::string16* text) const OVERRIDE;
virtual void OnInputMethodChanged() OVERRIDE;
virtual bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) OVERRIDE;
@@ -395,6 +396,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
DiscardDelegatedFrames);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SoftwareDPIChange);
class WindowObserver;
friend class WindowObserver;
@@ -487,9 +489,16 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
scoped_ptr<cc::CopyOutputResult> result);
static void CopyFromCompositingSurfaceHasResultForVideo(
base::WeakPtr<RenderWidgetHostViewAura> rwhva,
+ scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_refptr<media::VideoFrame> video_frame,
const base::Callback<void(bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result);
+ static void CopyFromCompositingSurfaceFinishedForVideo(
+ base::WeakPtr<RenderWidgetHostViewAura> rwhva,
+ const base::Callback<void(bool)>& callback,
+ scoped_refptr<OwnedMailbox> subscriber_texture,
+ scoped_ptr<cc::SingleReleaseCallback> release_callback,
+ bool result);
ui::Compositor* GetCompositor() const;
@@ -575,6 +584,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// after requesting shutdown for another reason (e.g. Escape key).
bool in_shutdown_;
+ // True if in the process of handling a window bounds changed notification.
+ bool in_bounds_changed_;
+
// Is this a fullscreen view?
bool is_fullscreen_;
@@ -619,7 +631,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool accept_return_character_;
// Current tooltip text.
- string16 tooltip_;
+ base::string16 tooltip_;
std::vector<base::Closure> on_compositing_did_commit_callbacks_;
@@ -747,6 +759,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// Subscriber that listens to frame presentation events.
scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_;
+ std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_;
// YUV readback pipeline.
scoped_ptr<content::ReadbackYUVInterface>
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index ee93871692..120956067d 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -973,8 +973,8 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
// Swap another frame, with a different surface id.
EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
- view_->OnSwapCompositorFrame(
- 3, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ view_->OnSwapCompositorFrame(3,
+ MakeDelegatedFrame(1.f, frame_size, view_rect));
testing::Mock::VerifyAndClearExpectations(&observer);
view_->RunOnCompositingDidCommit();
@@ -1080,4 +1080,35 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
}
}
+TEST_F(RenderWidgetHostViewAuraTest, SoftwareDPIChange) {
+ gfx::Rect view_rect(100, 100);
+ gfx::Size frame_size(100, 100);
+
+ view_->InitAsChild(NULL);
+ aura::client::ParentWindowWithContext(
+ view_->GetNativeView(),
+ parent_view_->GetNativeView()->GetRootWindow(),
+ gfx::Rect());
+ view_->SetSize(view_rect.size());
+ view_->WasShown();
+
+ // With a 1x DPI UI and 1x DPI Renderer.
+ view_->OnSwapCompositorFrame(
+ 1, MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)));
+
+ // Save the frame provider.
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
+ view_->frame_provider_;
+
+ // This frame will have the same number of physical pixels, but has a new
+ // scale on it.
+ view_->OnSwapCompositorFrame(
+ 1, MakeDelegatedFrame(2.f, frame_size, gfx::Rect(frame_size)));
+
+ // When we get a new frame with the same frame size in physical pixels, but a
+ // different scale, we should generate a new frame provider, as the final
+ // result will need to be scaled differently to the screen.
+ EXPECT_NE(frame_provider.get(), view_->frame_provider_.get());
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index b96182c7d9..8347b6d57f 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -118,7 +118,7 @@ LRESULT CALLBACK PluginWrapperWindowProc(HWND window, unsigned int message,
bool IsPluginWrapperWindow(HWND window) {
return gfx::GetClassNameW(window) ==
- string16(kWrapperNativeWindowClassName);
+ base::string16(kWrapperNativeWindowClassName);
}
// Create an intermediate window between the given HWND and its parent.
@@ -421,7 +421,7 @@ float RenderWidgetHostViewBase::GetOverdrawBottomHeight() const {
return 0.f;
}
-void RenderWidgetHostViewBase::SelectionChanged(const string16& text,
+void RenderWidgetHostViewBase::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
selection_text_ = text;
@@ -439,9 +439,9 @@ void RenderWidgetHostViewBase::SetShowingContextMenu(bool showing) {
showing_context_menu_ = showing;
}
-string16 RenderWidgetHostViewBase::GetSelectedText() const {
+base::string16 RenderWidgetHostViewBase::GetSelectedText() const {
if (!selection_range_.IsValid())
- return string16();
+ return base::string16();
return selection_text_.substr(
selection_range_.GetMin() - selection_text_offset_,
selection_range_.length());
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 0a6fd1ac22..eadf92b87d 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -47,7 +47,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// RenderWidgetHostViewPort implementation.
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
@@ -56,7 +56,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
virtual float GetOverdrawBottomHeight() const OVERRIDE;
virtual bool IsShowingContextMenu() const OVERRIDE;
virtual void SetShowingContextMenu(bool showing_menu) OVERRIDE;
- virtual string16 GetSelectedText() const OVERRIDE;
+ virtual base::string16 GetSelectedText() const OVERRIDE;
virtual bool IsMouseLocked() OVERRIDE;
virtual void UnhandledWheelEvent(
const blink::WebMouseWheelEvent& event) OVERRIDE;
@@ -140,7 +140,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
bool showing_context_menu_;
// A buffer containing the text inside and around the current selection range.
- string16 selection_text_;
+ base::string16 selection_text_;
// The offset of the text stored in |selection_text_| relative to the start of
// the web page.
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc
index 494ba38f86..e50bd04565 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -929,14 +929,15 @@ void RenderWidgetHostViewGtk::Destroy() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
-void RenderWidgetHostViewGtk::SetTooltipText(const string16& tooltip_text) {
+void RenderWidgetHostViewGtk::SetTooltipText(
+ const base::string16& tooltip_text) {
// Maximum number of characters we allow in a tooltip.
const int kMaxTooltipLength = 8 << 10;
// Clamp the tooltip length to kMaxTooltipLength so that we don't
// accidentally DOS the user with a mega tooltip (since GTK doesn't do
// this itself).
// I filed https://bugzilla.gnome.org/show_bug.cgi?id=604641 upstream.
- const string16 clamped_tooltip =
+ const base::string16 clamped_tooltip =
gfx::TruncateString(tooltip_text, kMaxTooltipLength);
if (clamped_tooltip.empty()) {
@@ -947,7 +948,7 @@ void RenderWidgetHostViewGtk::SetTooltipText(const string16& tooltip_text) {
}
}
-void RenderWidgetHostViewGtk::SelectionChanged(const string16& text,
+void RenderWidgetHostViewGtk::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
@@ -1347,13 +1348,20 @@ bool RenderWidgetHostViewGtk::LockMouse() {
}
// Clear the tooltip window.
- SetTooltipText(string16());
+ SetTooltipText(base::string16());
// Ensure that the widget center location will be relevant for this mouse
// lock session. It is updated whenever the window geometry moves
// but may be out of date due to switching tabs.
MarkCachedWidgetCenterStale();
+ // Ensure that if we were previously warping the cursor to a specific point
+ // that we no longer track doing so when entering lock. It should be cleared
+ // by the cursor moving to the warp point, and this shouldn't be necessary.
+ // But, this is a small effort to ensure robustness in the event a warp isn't
+ // completed.
+ mouse_is_being_warped_to_unlocked_position_ = false;
+
return true;
}
@@ -1411,7 +1419,7 @@ bool RenderWidgetHostViewGtk::RetrieveSurrounding(std::string* text,
*text = base::UTF16ToUTF8AndAdjustOffset(
base::StringPiece16(selection_text_), &offset);
- if (offset == string16::npos) {
+ if (offset == base::string16::npos) {
NOTREACHED() << "Invalid offset in UTF16 string.";
return false;
}
@@ -1484,7 +1492,7 @@ void RenderWidgetHostViewGtk::ModifyEventMovementAndCoords(
event->windowY = unlocked_mouse_position_.y();
event->globalX = unlocked_global_mouse_position_.x();
event->globalY = unlocked_global_mouse_position_.y();
- } else {
+ } else if (!mouse_is_being_warped_to_unlocked_position_) {
unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
}
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.h b/content/browser/renderer_host/render_widget_host_view_gtk.h
index 9bb2755e39..e01181ab4c 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.h
@@ -93,8 +93,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGtk
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SelectionBoundsChanged(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc
index 629938495b..907119de3c 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest.cc
@@ -169,7 +169,8 @@ void RenderWidgetHostViewGuest::Destroy() {
platform_view_->Destroy();
}
-void RenderWidgetHostViewGuest::SetTooltipText(const string16& tooltip_text) {
+void RenderWidgetHostViewGuest::SetTooltipText(
+ const base::string16& tooltip_text) {
platform_view_->SetTooltipText(tooltip_text);
}
@@ -324,7 +325,7 @@ void RenderWidgetHostViewGuest::DidUpdateBackingStore(
NOTREACHED();
}
-void RenderWidgetHostViewGuest::SelectionChanged(const string16& text,
+void RenderWidgetHostViewGuest::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
platform_view_->SelectionChanged(text, offset, range);
@@ -346,9 +347,10 @@ BackingStore* RenderWidgetHostViewGuest::AllocBackingStore(
void RenderWidgetHostViewGuest::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
- const gfx::Size& /* dst_size */,
+ const gfx::Size& dst_size,
const base::Callback<void(bool, const SkBitmap&)>& callback) {
- callback.Run(false, SkBitmap());
+ CHECK(guest_);
+ guest_->CopyFromCompositingSurface(src_subrect, dst_size, callback);
}
void RenderWidgetHostViewGuest::CopyFromCompositingSurfaceToVideoFrame(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest.h b/content/browser/renderer_host/render_widget_host_view_guest.h
index e406b50fa5..ac9fa0ee2c 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest.h
+++ b/content/browser/renderer_host/render_widget_host_view_guest.h
@@ -98,8 +98,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SelectionBoundsChanged(
diff --git a/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc b/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
index a112634b69..b99743aa5f 100644
--- a/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_guest_unittest.cc
@@ -8,11 +8,11 @@
#include "base/message_loop/message_loop.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index 4a667b0ab2..00c4282eca 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -108,10 +108,10 @@ class RenderWidgetHostViewMacEditCommandHelper;
NSRange selectedRange_;
// Text to be inserted which was generated by handling a key down event.
- string16 textToBeInserted_;
+ base::string16 textToBeInserted_;
// Marked text which was generated by handling a key down event.
- string16 markedText_;
+ base::string16 markedText_;
// Underline information of the |markedText_|.
std::vector<blink::WebCompositionUnderline> underlines_;
@@ -264,8 +264,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
virtual void RenderProcessGone(base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void Destroy() OVERRIDE;
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
- virtual void SelectionChanged(const string16& text,
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
+ virtual void SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) OVERRIDE;
virtual void SelectionBoundsChanged(
@@ -338,7 +338,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
void EnableCoreAnimation();
// Sends completed plugin IME notification and text back to the renderer.
- void PluginImeCompositionCompleted(const string16& text, int plugin_id);
+ void PluginImeCompositionCompleted(const base::string16& text, int plugin_id);
const std::string& selected_text() const { return selected_text_; }
@@ -355,6 +355,15 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
// Called when a GPU error is detected. Deletes all compositing state.
void GotAcceleratedCompositingError();
+ // Sets the overlay view, which should be drawn in the same IOSurface
+ // atop of this view, if both views are drawing accelerated content.
+ // Overlay is stored as a weak ptr.
+ void SetOverlayView(RenderWidgetHostViewMac* overlay,
+ const gfx::Point& offset);
+
+ // Removes the previously set overlay view.
+ void RemoveOverlayView();
+
// Returns true and stores first rectangle for character range if the
// requested |range| is already cached, otherwise returns false.
// Exposed for testing.
@@ -526,7 +535,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
bool is_loading_;
// The text to be shown in the tooltip, supplied by the renderer.
- string16 tooltip_text_;
+ base::string16 tooltip_text_;
// Factory used to safely scope delayed calls to ShutdownHost().
base::WeakPtrFactory<RenderWidgetHostViewMac> weak_factory_;
@@ -551,6 +560,27 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
base::WeakPtrFactory<RenderWidgetHostViewMac>
pending_swap_buffers_acks_weak_factory_;
+ // The overlay view which is rendered above this one in the same
+ // accelerated IOSurface.
+ // Overlay view has |underlay_view_| set to this view.
+ base::WeakPtr<RenderWidgetHostViewMac> overlay_view_;
+
+ // Offset at which overlay view should be rendered.
+ gfx::Point overlay_view_offset_;
+
+ // The underlay view which this view is rendered above in the same
+ // accelerated IOSurface.
+ // Underlay view has |overlay_view_| set to this view.
+ base::WeakPtr<RenderWidgetHostViewMac> underlay_view_;
+
+ // Set to true when |underlay_view_| has drawn this view. After that point,
+ // this view should not draw again until |underlay_view_| is changed.
+ bool underlay_view_has_drawn_;
+
+ // Factory used to safely reference overlay view set in SetOverlayView.
+ base::WeakPtrFactory<RenderWidgetHostViewMac>
+ overlay_view_weak_factory_;
+
// The earliest time at which the next swap ack may be sent. Only relevant
// when swaps are not being throttled by the renderer (when threaded
// compositing is off).
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index acfd3b6aee..9b5de7fdcf 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -418,6 +418,8 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
weak_factory_(this),
fullscreen_parent_host_view_(NULL),
pending_swap_buffers_acks_weak_factory_(this),
+ underlay_view_has_drawn_(false),
+ overlay_view_weak_factory_(this),
next_swap_ack_time_(base::Time::Now()),
software_frame_weak_ptr_factory_(this) {
software_frame_manager_.reset(new SoftwareFrameManager(
@@ -1019,7 +1021,8 @@ void RenderWidgetHostViewMac::Destroy() {
// Called from the renderer to tell us what the tooltip text should be. It
// calls us frequently so we need to cache the value to prevent doing a lot
// of repeat work.
-void RenderWidgetHostViewMac::SetTooltipText(const string16& tooltip_text) {
+void RenderWidgetHostViewMac::SetTooltipText(
+ const base::string16& tooltip_text) {
if (tooltip_text != tooltip_text_ && [[cocoa_view_ window] isKeyWindow]) {
tooltip_text_ = tooltip_text;
@@ -1027,7 +1030,7 @@ void RenderWidgetHostViewMac::SetTooltipText(const string16& tooltip_text) {
// Windows; we're just trying to be polite. Don't persist the trimmed
// string, as then the comparison above will always fail and we'll try to
// set it again every single time the mouse moves.
- string16 display_text = tooltip_text_;
+ base::string16 display_text = tooltip_text_;
if (tooltip_text_.length() > kMaxTooltipLength)
display_text = tooltip_text_.substr(0, kMaxTooltipLength);
@@ -1060,7 +1063,7 @@ void RenderWidgetHostViewMac::StopSpeaking() {
// RenderWidgetHostViewCocoa uses the stored selection text,
// which implements NSServicesRequests protocol.
//
-void RenderWidgetHostViewMac::SelectionChanged(const string16& text,
+void RenderWidgetHostViewMac::SelectionChanged(const base::string16& text,
size_t offset,
const gfx::Range& range) {
if (range.is_empty() || text.empty()) {
@@ -1245,7 +1248,7 @@ bool RenderWidgetHostViewMac::PostProcessEventForPluginIme(
}
void RenderWidgetHostViewMac::PluginImeCompositionCompleted(
- const string16& text, int plugin_id) {
+ const base::string16& text, int plugin_id) {
if (render_widget_host_) {
render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted(
render_widget_host_->GetRoutingID(), text, plugin_id));
@@ -1418,6 +1421,14 @@ bool RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() {
forParameter:NSOpenGLCPSurfaceOrder];
}
+ // Instead of drawing, request that underlay view redraws.
+ if (underlay_view_ &&
+ underlay_view_->compositing_iosurface_ &&
+ underlay_view_has_drawn_) {
+ [underlay_view_->cocoa_view() setNeedsDisplay:YES];
+ return true;
+ }
+
CGLError cgl_error = CGLSetCurrentContext(
compositing_iosurface_context_->cgl_context());
if (cgl_error != kCGLNoError) {
@@ -1426,12 +1437,35 @@ bool RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() {
}
[compositing_iosurface_context_->nsgl_context() setView:cocoa_view_];
- return compositing_iosurface_->DrawIOSurface(
+ bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_;
+
+ gfx::Rect view_rect(NSRectToCGRect([cocoa_view_ frame]));
+ if (!compositing_iosurface_->DrawIOSurface(
compositing_iosurface_context_,
- gfx::Rect(NSRectToCGRect([cocoa_view_ frame])),
+ view_rect,
scale_factor(),
frame_subscriber(),
- true);
+ !has_overlay)) {
+ return false;
+ }
+
+ if (has_overlay) {
+ overlay_view_->underlay_view_has_drawn_ = true;
+ gfx::Rect overlay_view_rect(
+ NSRectToCGRect([overlay_view_->cocoa_view() frame]));
+ overlay_view_rect.set_x(overlay_view_offset_.x());
+ overlay_view_rect.set_y(view_rect.height() -
+ overlay_view_rect.height() -
+ overlay_view_offset_.y());
+ return overlay_view_->compositing_iosurface_->DrawIOSurface(
+ compositing_iosurface_context_,
+ overlay_view_rect,
+ overlay_view_->scale_factor(),
+ overlay_view_->frame_subscriber(),
+ true);
+ }
+
+ return true;
}
void RenderWidgetHostViewMac::GotAcceleratedCompositingError() {
@@ -1448,6 +1482,29 @@ void RenderWidgetHostViewMac::GotAcceleratedCompositingError() {
// repeatedly.
}
+void RenderWidgetHostViewMac::SetOverlayView(
+ RenderWidgetHostViewMac* overlay, const gfx::Point& offset) {
+ if (overlay_view_)
+ overlay_view_->underlay_view_.reset();
+
+ overlay_view_ = overlay->overlay_view_weak_factory_.GetWeakPtr();
+ overlay_view_offset_ = offset;
+ overlay_view_->underlay_view_ = overlay_view_weak_factory_.GetWeakPtr();
+ overlay_view_->underlay_view_has_drawn_ = false;
+
+ [cocoa_view_ setNeedsDisplay:YES];
+ [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
+}
+
+void RenderWidgetHostViewMac::RemoveOverlayView() {
+ if (overlay_view_) {
+ overlay_view_->underlay_view_.reset();
+ overlay_view_.reset();
+ }
+ [cocoa_view_ setNeedsDisplay:YES];
+ [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
+}
+
void RenderWidgetHostViewMac::GetVSyncParameters(
base::TimeTicks* timebase, base::TimeDelta* interval) {
if (compositing_iosurface_) {
@@ -1745,7 +1802,7 @@ bool RenderWidgetHostViewMac::LockMouse() {
[NSCursor hide];
// Clear the tooltip window.
- SetTooltipText(string16());
+ SetTooltipText(base::string16());
return true;
}
@@ -1956,7 +2013,6 @@ void RenderWidgetHostViewMac::FrameSwapped() {
// RenderWidgetHostViewCocoa ---------------------------------------------------
@implementation RenderWidgetHostViewCocoa
-
@synthesize selectedRange = selectedRange_;
@synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_;
@synthesize markedRange = markedRange_;
@@ -1965,6 +2021,7 @@ void RenderWidgetHostViewMac::FrameSwapped() {
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
self = [super initWithFrame:NSZeroRect];
if (self) {
+ self.acceptsTouchEvents = YES;
editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper);
editCommand_helper_->AddEditingSelectorsToClass([self class]);
@@ -2018,8 +2075,8 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right {
- if (delegate_ && [delegate_ respondsToSelector:
- @selector(scrollOffsetPinnedToLeft:toRight:)]) {
+ if (delegate_ && [delegate_
+ respondsToSelector:@selector(scrollOffsetPinnedToLeft:toRight:)]) {
[delegate_ scrollOffsetPinnedToLeft:left toRight:right];
}
}
@@ -2098,10 +2155,16 @@ void RenderWidgetHostViewMac::FrameSwapped() {
// The cursor is over a nonWebContentView - ignore this mouse event.
return YES;
}
- if ([view isKindOfClass:[self class]] && ![view isEqual:self]) {
+ if ([view isKindOfClass:[self class]] && ![view isEqual:self] &&
+ !hasOpenMouseDown_) {
// The cursor is over an overlapping render widget. This check is done by
// both views so the one that's returned by -hitTest: will end up
// processing the event.
+ // Note that while dragging, we only get events for the render view where
+ // drag started, even if mouse is actually over another view or outside
+ // the window. Cocoa does this for us. We should handle these events and
+ // not ignore (since there is no other render view to handle them). Thus
+ // the |!hasOpenMouseDown_| check above.
return YES;
}
view = [view superview];
@@ -2393,7 +2456,7 @@ void RenderWidgetHostViewMac::FrameSwapped() {
} else if (oldHasMarkedText && !hasMarkedText_ && !textInserted) {
if (unmarkTextCalled_) {
widgetHost->ImeConfirmComposition(
- string16(), gfx::Range::InvalidRange(), false);
+ base::string16(), gfx::Range::InvalidRange(), false);
} else {
widgetHost->ImeCancelComposition();
}
@@ -2479,6 +2542,47 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
}
+- (void)beginGestureWithEvent:(NSEvent*)event {
+ [delegate_ beginGestureWithEvent:event];
+}
+- (void)endGestureWithEvent:(NSEvent*)event {
+ [delegate_ endGestureWithEvent:event];
+}
+- (void)touchesMovedWithEvent:(NSEvent*)event {
+ [delegate_ touchesMovedWithEvent:event];
+}
+- (void)touchesBeganWithEvent:(NSEvent*)event {
+ [delegate_ touchesBeganWithEvent:event];
+}
+- (void)touchesCancelledWithEvent:(NSEvent*)event {
+ [delegate_ touchesCancelledWithEvent:event];
+}
+- (void)touchesEndedWithEvent:(NSEvent*)event {
+ [delegate_ touchesEndedWithEvent:event];
+}
+
+// This method handles 2 different types of hardware events.
+// (Apple does not distinguish between them).
+// a. Scrolling the middle wheel of a mouse.
+// b. Swiping on the track pad.
+//
+// This method is responsible for 2 types of behavior:
+// a. Scrolling the content of window.
+// b. Navigating forwards/backwards in history.
+//
+// This is a brief description of the logic:
+// 1. If the content can be scrolled, scroll the content.
+// (This requires a roundtrip to blink to determine whether the content
+// can be scrolled.)
+// Once this logic is triggered, the navigate logic cannot be triggered
+// until the gesture finishes.
+// 2. If the user is making a horizontal swipe, start the navigate
+// forward/backwards UI.
+// Once this logic is triggered, the user can either cancel or complete
+// the gesture. If the user completes the gesture, all remaining touches
+// are swallowed, and not allowed to scroll the content. If the user
+// cancels the gesture, all remaining touches are forwarded to the content
+// scroll logic. The user cannot trigger the navigation logic again.
- (void)scrollWheel:(NSEvent*)event {
if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) {
BOOL handled = [delegate_ handleEvent:event];
@@ -2493,13 +2597,14 @@ void RenderWidgetHostViewMac::FrameSwapped() {
if (base::mac::IsOSLionOrLater() && [event phase] == NSEventPhaseBegan &&
!endWheelMonitor_) {
endWheelMonitor_ =
- [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask
- handler:^(NSEvent* blockEvent) {
- [self shortCircuitScrollWheelEvent:blockEvent];
- return blockEvent;
- }];
+ [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask
+ handler:^(NSEvent* blockEvent) {
+ [self shortCircuitScrollWheelEvent:blockEvent];
+ return blockEvent;
+ }];
}
+ // This is responsible for content scrolling!
if (renderWidgetHostView_->render_widget_host_) {
const WebMouseWheelEvent& webEvent =
WebInputEventFactory::mouseWheelEvent(event, self);
@@ -2931,8 +3036,9 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
- if (delegate_ && [delegate_ respondsToSelector:
- @selector(validateUserInterfaceItem:isValidItem:)]) {
+ if (delegate_ &&
+ [delegate_ respondsToSelector:@selector(validateUserInterfaceItem:
+ isValidItem:)]) {
BOOL valid;
BOOL known = [delegate_ validateUserInterfaceItem:item
isValidItem:&valid];
@@ -3506,7 +3612,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
// called in keyEvent: method.
if (!handlingKeyDown_) {
renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(
- string16(), gfx::Range::InvalidRange(), false);
+ base::string16(), gfx::Range::InvalidRange(), false);
} else {
unmarkTextCalled_ = YES;
}
@@ -3744,7 +3850,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
if (renderWidgetHostView_->render_widget_host_)
renderWidgetHostView_->render_widget_host_->ImeConfirmComposition(
- string16(), gfx::Range::InvalidRange(), false);
+ base::string16(), gfx::Range::InvalidRange(), false);
[self cancelComposition];
}
@@ -3757,7 +3863,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
if (!active) {
[[ComplexTextInputPanel sharedComplexTextInputPanel] cancelComposition];
renderWidgetHostView_->PluginImeCompositionCompleted(
- string16(), focusedPluginIdentifier_);
+ base::string16(), focusedPluginIdentifier_);
}
}
@@ -3792,7 +3898,7 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
if (pluginImeActive_ &&
![[ComplexTextInputPanel sharedComplexTextInputPanel] inComposition]) {
renderWidgetHostView_->PluginImeCompositionCompleted(
- string16(), focusedPluginIdentifier_);
+ base::string16(), focusedPluginIdentifier_);
pluginImeActive_ = NO;
}
}
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index ad37bfdd35..2515496216 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -9,7 +9,6 @@
#include "base/strings/utf_string_conversions.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
@@ -18,6 +17,7 @@
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_utils.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/test/cocoa_test_event_utils.h"
@@ -83,6 +83,12 @@ typedef NSUInteger NSEventPhase;
- (void)gotUnhandledWheelEvent {
unhandledWheelEventReceived_ = true;
}
+- (void)touchesBeganWithEvent:(NSEvent*)event{}
+- (void)touchesMovedWithEvent:(NSEvent*)event{}
+- (void)touchesCancelledWithEvent:(NSEvent*)event{}
+- (void)touchesEndedWithEvent:(NSEvent*)event{}
+- (void)beginGestureWithEvent:(NSEvent*)event{}
+- (void)endGestureWithEvent:(NSEvent*)event{}
@end
@@ -318,7 +324,7 @@ TEST_F(RenderWidgetHostViewMacTest, AcceleratorDestroy) {
}
TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) {
- const string16 kDummyString = UTF8ToUTF16("hogehoge");
+ const base::string16 kDummyString = UTF8ToUTF16("hogehoge");
const size_t kDummyOffset = 0;
gfx::Rect caret_rect(10, 11, 0, 10);
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index c07a989409..8238a82b4c 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -836,14 +836,15 @@ void RenderWidgetHostViewWin::Destroy() {
DestroyWindow();
}
-void RenderWidgetHostViewWin::SetTooltipText(const string16& tooltip_text) {
+void RenderWidgetHostViewWin::SetTooltipText(
+ const base::string16& tooltip_text) {
if (!render_widget_host_->is_hidden())
EnsureTooltip();
// Clamp the tooltip length to kMaxTooltipLength so that we don't
// accidentally DOS the user with a mega tooltip (since Windows doesn't seem
// to do this itself).
- const string16 new_tooltip_text =
+ const base::string16 new_tooltip_text =
gfx::TruncateString(tooltip_text, kMaxTooltipLength);
if (new_tooltip_text != tooltip_text_) {
@@ -1017,7 +1018,7 @@ void RenderWidgetHostViewWin::ClearCompositionText() {
NOTIMPLEMENTED();
}
-void RenderWidgetHostViewWin::InsertText(const string16& text) {
+void RenderWidgetHostViewWin::InsertText(const base::string16& text) {
if (!base::win::IsTSFAwareRequired()) {
NOTREACHED();
return;
@@ -1153,7 +1154,7 @@ bool RenderWidgetHostViewWin::DeleteRange(const gfx::Range& range) {
}
bool RenderWidgetHostViewWin::GetTextFromRange(const gfx::Range& range,
- string16* text) const {
+ base::string16* text) const {
if (!base::win::IsTSFAwareRequired()) {
NOTREACHED();
return false;
diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h
index 72b22aa756..b9a87bf61e 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.h
+++ b/content/browser/renderer_host/render_widget_host_view_win.h
@@ -202,7 +202,7 @@ class RenderWidgetHostViewWin
// called by WebContentsImpl before DestroyWindow
virtual void WillWmDestroy() OVERRIDE;
virtual void Destroy() OVERRIDE;
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE;
+ virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE;
virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
virtual void CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
@@ -270,7 +270,7 @@ class RenderWidgetHostViewWin
const ui::CompositionText& composition) OVERRIDE;
virtual void ConfirmCompositionText() OVERRIDE;
virtual void ClearCompositionText() OVERRIDE;
- virtual void InsertText(const string16& text) OVERRIDE;
+ virtual void InsertText(const base::string16& text) OVERRIDE;
virtual void InsertChar(char16 ch, int flags) OVERRIDE;
virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE;
virtual ui::TextInputType GetTextInputType() const OVERRIDE;
@@ -286,7 +286,7 @@ class RenderWidgetHostViewWin
virtual bool SetSelectionRange(const gfx::Range& range) OVERRIDE;
virtual bool DeleteRange(const gfx::Range& range) OVERRIDE;
virtual bool GetTextFromRange(const gfx::Range& range,
- string16* text) const OVERRIDE;
+ base::string16* text) const OVERRIDE;
virtual void OnInputMethodChanged() OVERRIDE;
virtual bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) OVERRIDE;
@@ -516,7 +516,7 @@ class RenderWidgetHostViewWin
// Tooltips
// The text to be shown in the tooltip, supplied by the renderer.
- string16 tooltip_text_;
+ base::string16 tooltip_text_;
// The tooltip control hwnd
HWND tooltip_hwnd_;
// Whether or not a tooltip is currently visible. We use this to track
diff --git a/content/browser/renderer_host/test_backing_store.cc b/content/browser/renderer_host/test_backing_store.cc
deleted file mode 100644
index 74fa44d487..0000000000
--- a/content/browser/renderer_host/test_backing_store.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/test_backing_store.h"
-
-namespace content {
-
-TestBackingStore::TestBackingStore(RenderWidgetHost* widget,
- const gfx::Size& size)
- : BackingStore(widget, size) {
-}
-
-TestBackingStore::~TestBackingStore() {
-}
-
-void TestBackingStore::PaintToBackingStore(
- RenderProcessHost* process,
- TransportDIB::Id bitmap,
- const gfx::Rect& bitmap_rect,
- const std::vector<gfx::Rect>& copy_rects,
- float scale_factor,
- const base::Closure& completion_callback,
- bool* scheduled_completion_callback) {
- *scheduled_completion_callback = false;
-}
-
-bool TestBackingStore::CopyFromBackingStore(const gfx::Rect& rect,
- skia::PlatformBitmap* output) {
- return false;
-}
-
-void TestBackingStore::ScrollBackingStore(const gfx::Vector2d& delta,
- const gfx::Rect& clip_rect,
- const gfx::Size& view_size) {
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/test_backing_store.h b/content/browser/renderer_host/test_backing_store.h
deleted file mode 100644
index 4b76851c74..0000000000
--- a/content/browser/renderer_host/test_backing_store.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_TEST_TEST_BACKING_STORE_H_
-#define CONTENT_BROWSER_RENDERER_HOST_TEST_TEST_BACKING_STORE_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "content/browser/renderer_host/backing_store.h"
-
-namespace content {
-
-class TestBackingStore : public BackingStore {
- public:
- TestBackingStore(RenderWidgetHost* widget, const gfx::Size& size);
- virtual ~TestBackingStore();
-
- // BackingStore implementation.
- virtual void PaintToBackingStore(
- RenderProcessHost* process,
- TransportDIB::Id bitmap,
- const gfx::Rect& bitmap_rect,
- const std::vector<gfx::Rect>& copy_rects,
- float scale_factor,
- const base::Closure& completion_callback,
- bool* scheduled_completion_callback) OVERRIDE;
- virtual bool CopyFromBackingStore(const gfx::Rect& rect,
- skia::PlatformBitmap* output) OVERRIDE;
- virtual void ScrollBackingStore(const gfx::Vector2d& delta,
- const gfx::Rect& clip_rect,
- const gfx::Size& view_size) OVERRIDE;
- private:
- DISALLOW_COPY_AND_ASSIGN(TestBackingStore);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_TEST_TEST_BACKING_STORE_H_
diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc
deleted file mode 100644
index 19d5958179..0000000000
--- a/content/browser/renderer_host/test_render_view_host.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/test_render_view_host.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
-#include "content/browser/dom_storage/session_storage_namespace_impl.h"
-#include "content/browser/renderer_host/test_backing_store.h"
-#include "content/browser/site_instance_impl.h"
-#include "content/common/dom_storage/dom_storage_types.h"
-#include "content/common/view_messages.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/page_state.h"
-#include "content/test/test_web_contents.h"
-#include "media/base/video_frame.h"
-#include "ui/gfx/rect.h"
-#include "webkit/common/webpreferences.h"
-
-namespace content {
-
-namespace {
-
-const int64 kFrameId = 13UL;
-
-} // namespace
-
-
-void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
- int page_id,
- const GURL& url,
- PageTransition transition) {
- params->page_id = page_id;
- params->url = url;
- params->referrer = Referrer();
- params->transition = transition;
- params->redirects = std::vector<GURL>();
- params->should_update_history = false;
- params->searchable_form_url = GURL();
- params->searchable_form_encoding = std::string();
- params->security_info = std::string();
- params->gesture = NavigationGestureUser;
- params->was_within_same_page = false;
- params->is_post = false;
- params->page_state = PageState::CreateFromURL(url);
-}
-
-TestRenderWidgetHostView::TestRenderWidgetHostView(RenderWidgetHost* rwh)
- : rwh_(RenderWidgetHostImpl::From(rwh)),
- is_showing_(false),
- did_swap_compositor_frame_(false) {
- rwh_->SetView(this);
-}
-
-TestRenderWidgetHostView::~TestRenderWidgetHostView() {
-}
-
-RenderWidgetHost* TestRenderWidgetHostView::GetRenderWidgetHost() const {
- return NULL;
-}
-
-gfx::NativeView TestRenderWidgetHostView::GetNativeView() const {
- return NULL;
-}
-
-gfx::NativeViewId TestRenderWidgetHostView::GetNativeViewId() const {
- return 0;
-}
-
-gfx::NativeViewAccessible TestRenderWidgetHostView::GetNativeViewAccessible() {
- return NULL;
-}
-
-bool TestRenderWidgetHostView::HasFocus() const {
- return true;
-}
-
-bool TestRenderWidgetHostView::IsSurfaceAvailableForCopy() const {
- return true;
-}
-
-void TestRenderWidgetHostView::Show() {
- is_showing_ = true;
-}
-
-void TestRenderWidgetHostView::Hide() {
- is_showing_ = false;
-}
-
-bool TestRenderWidgetHostView::IsShowing() {
- return is_showing_;
-}
-
-void TestRenderWidgetHostView::RenderProcessGone(base::TerminationStatus status,
- int error_code) {
- delete this;
-}
-
-void TestRenderWidgetHostView::Destroy() { delete this; }
-
-gfx::Rect TestRenderWidgetHostView::GetViewBounds() const {
- return gfx::Rect();
-}
-
-BackingStore* TestRenderWidgetHostView::AllocBackingStore(
- const gfx::Size& size) {
- return new TestBackingStore(rwh_, size);
-}
-
-void TestRenderWidgetHostView::CopyFromCompositingSurface(
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- const base::Callback<void(bool, const SkBitmap&)>& callback) {
- callback.Run(false, SkBitmap());
-}
-
-void TestRenderWidgetHostView::CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) {
- callback.Run(false);
-}
-
-bool TestRenderWidgetHostView::CanCopyToVideoFrame() const {
- return false;
-}
-
-void TestRenderWidgetHostView::OnAcceleratedCompositingStateChange() {
-}
-
-void TestRenderWidgetHostView::AcceleratedSurfaceInitialized(int host_id,
- int route_id) {
-}
-
-void TestRenderWidgetHostView::AcceleratedSurfaceBuffersSwapped(
- const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
- int gpu_host_id) {
-}
-
-void TestRenderWidgetHostView::AcceleratedSurfacePostSubBuffer(
- const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
- int gpu_host_id) {
-}
-
-void TestRenderWidgetHostView::AcceleratedSurfaceSuspend() {
-}
-
-bool TestRenderWidgetHostView::HasAcceleratedSurface(
- const gfx::Size& desired_size) {
- return false;
-}
-
-#if defined(OS_MACOSX)
-
-void TestRenderWidgetHostView::AboutToWaitForBackingStoreMsg() {
-}
-
-void TestRenderWidgetHostView::SetActive(bool active) {
- // <viettrungluu@gmail.com>: Do I need to do anything here?
-}
-
-bool TestRenderWidgetHostView::SupportsSpeech() const {
- return false;
-}
-
-void TestRenderWidgetHostView::SpeakSelection() {
-}
-
-bool TestRenderWidgetHostView::IsSpeaking() const {
- return false;
-}
-
-void TestRenderWidgetHostView::StopSpeaking() {
-}
-
-bool TestRenderWidgetHostView::PostProcessEventForPluginIme(
- const NativeWebKeyboardEvent& event) {
- return false;
-}
-
-#elif defined(OS_WIN) && !defined(USE_AURA)
-void TestRenderWidgetHostView::WillWmDestroy() {
-}
-#endif
-
-gfx::Rect TestRenderWidgetHostView::GetBoundsInRootWindow() {
- return gfx::Rect();
-}
-
-#if defined(TOOLKIT_GTK)
-GdkEventButton* TestRenderWidgetHostView::GetLastMouseDown() {
- return NULL;
-}
-
-gfx::NativeView TestRenderWidgetHostView::BuildInputMethodsGtkMenu() {
- return NULL;
-}
-#endif // defined(TOOLKIT_GTK)
-
-void TestRenderWidgetHostView::OnSwapCompositorFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::CompositorFrame> frame) {
- did_swap_compositor_frame_ = true;
-}
-
-
-gfx::GLSurfaceHandle TestRenderWidgetHostView::GetCompositingSurface() {
- return gfx::GLSurfaceHandle();
-}
-
-#if defined(OS_WIN) && !defined(USE_AURA)
-void TestRenderWidgetHostView::SetClickthroughRegion(SkRegion* region) {
-}
-#endif
-
-bool TestRenderWidgetHostView::LockMouse() {
- return false;
-}
-
-void TestRenderWidgetHostView::UnlockMouse() {
-}
-
-#if defined(OS_WIN) && defined(USE_AURA)
-void TestRenderWidgetHostView::SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) {
-}
-
-gfx::NativeViewId TestRenderWidgetHostView::GetParentForWindowlessPlugin()
- const {
- return 0;
-}
-#endif
-
-TestRenderViewHost::TestRenderViewHost(
- SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- RenderWidgetHostDelegate* widget_delegate,
- int routing_id,
- int main_frame_routing_id,
- bool swapped_out)
- : RenderViewHostImpl(instance,
- delegate,
- widget_delegate,
- routing_id,
- main_frame_routing_id,
- swapped_out,
- false /* hidden */),
- render_view_created_(false),
- delete_counter_(NULL),
- simulate_fetch_via_proxy_(false),
- simulate_history_list_was_cleared_(false),
- contents_mime_type_("text/html"),
- opener_route_id_(MSG_ROUTING_NONE) {
- // TestRenderWidgetHostView installs itself into this->view_ in its
- // constructor, and deletes itself when TestRenderWidgetHostView::Destroy() is
- // called.
- new TestRenderWidgetHostView(this);
-
- main_frame_id_ = kFrameId;
-}
-
-TestRenderViewHost::~TestRenderViewHost() {
- if (delete_counter_)
- ++*delete_counter_;
-}
-
-bool TestRenderViewHost::CreateRenderView(
- const string16& frame_name,
- int opener_route_id,
- int32 max_page_id) {
- DCHECK(!render_view_created_);
- render_view_created_ = true;
- opener_route_id_ = opener_route_id;
- return true;
-}
-
-bool TestRenderViewHost::IsRenderViewLive() const {
- return render_view_created_;
-}
-
-void TestRenderViewHost::SendNavigate(int page_id, const GURL& url) {
- SendNavigateWithTransition(page_id, url, PAGE_TRANSITION_LINK);
-}
-
-void TestRenderViewHost::SendFailedNavigate(int page_id, const GURL& url) {
- SendNavigateWithTransitionAndResponseCode(
- page_id, url, PAGE_TRANSITION_LINK, 500);
-}
-
-void TestRenderViewHost::SendNavigateWithTransition(
- int page_id, const GURL& url, PageTransition transition) {
- SendNavigateWithTransitionAndResponseCode(page_id, url, transition, 200);
-}
-
-void TestRenderViewHost::SendNavigateWithOriginalRequestURL(
- int page_id, const GURL& url, const GURL& original_request_url) {
- OnDidStartProvisionalLoadForFrame(kFrameId, -1, true, url);
- SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK,
- original_request_url, 200, 0);
-}
-
-void TestRenderViewHost::SendNavigateWithFile(
- int page_id, const GURL& url, const base::FilePath& file_path) {
- SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK,
- url, 200, &file_path);
-}
-
-void TestRenderViewHost::SendNavigateWithTransitionAndResponseCode(
- int page_id, const GURL& url, PageTransition transition,
- int response_code) {
- // DidStartProvisionalLoad may delete the pending entry that holds |url|,
- // so we keep a copy of it to use in SendNavigateWithParameters.
- GURL url_copy(url);
- OnDidStartProvisionalLoadForFrame(kFrameId, -1, true, url_copy);
- SendNavigateWithParameters(page_id, url_copy, transition, url_copy,
- response_code, 0);
-}
-
-void TestRenderViewHost::SendNavigateWithParameters(
- int page_id, const GURL& url, PageTransition transition,
- const GURL& original_request_url, int response_code,
- const base::FilePath* file_path_for_history_item) {
- ViewHostMsg_FrameNavigate_Params params;
- params.page_id = page_id;
- params.frame_id = kFrameId;
- params.url = url;
- params.referrer = Referrer();
- params.transition = transition;
- params.redirects = std::vector<GURL>();
- params.should_update_history = true;
- params.searchable_form_url = GURL();
- params.searchable_form_encoding = std::string();
- params.security_info = std::string();
- params.gesture = NavigationGestureUser;
- params.contents_mime_type = contents_mime_type_;
- params.is_post = false;
- params.was_within_same_page = false;
- params.http_status_code = response_code;
- params.socket_address.set_host("2001:db8::1");
- params.socket_address.set_port(80);
- params.was_fetched_via_proxy = simulate_fetch_via_proxy_;
- params.history_list_was_cleared = simulate_history_list_was_cleared_;
- params.original_request_url = original_request_url;
-
- params.page_state = PageState::CreateForTesting(
- url,
- false,
- file_path_for_history_item ? "data" : NULL,
- file_path_for_history_item);
-
- ViewHostMsg_FrameNavigate msg(1, params);
- OnNavigate(msg);
-}
-
-void TestRenderViewHost::SendShouldCloseACK(bool proceed) {
- base::TimeTicks now = base::TimeTicks::Now();
- OnShouldCloseACK(proceed, now, now);
-}
-
-void TestRenderViewHost::SetContentsMimeType(const std::string& mime_type) {
- contents_mime_type_ = mime_type;
-}
-
-void TestRenderViewHost::SimulateSwapOutACK() {
- OnSwappedOut(false);
-}
-
-void TestRenderViewHost::SimulateWasHidden() {
- WasHidden();
-}
-
-void TestRenderViewHost::SimulateWasShown() {
- WasShown();
-}
-
-void TestRenderViewHost::TestOnStartDragging(
- const DropData& drop_data) {
- blink::WebDragOperationsMask drag_operation = blink::WebDragOperationEvery;
- DragEventSourceInfo event_info;
- OnStartDragging(drop_data, drag_operation, SkBitmap(), gfx::Vector2d(),
- event_info);
-}
-
-void TestRenderViewHost::TestOnUpdateStateWithFile(
- int process_id,
- const base::FilePath& file_path) {
- OnUpdateState(process_id,
- PageState::CreateForTesting(GURL("http://www.google.com"),
- false,
- "data",
- &file_path));
-}
-
-void TestRenderViewHost::set_simulate_fetch_via_proxy(bool proxy) {
- simulate_fetch_via_proxy_ = proxy;
-}
-
-void TestRenderViewHost::set_simulate_history_list_was_cleared(bool cleared) {
- simulate_history_list_was_cleared_ = cleared;
-}
-
-RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() {
- std::vector<ui::ScaleFactor> scale_factors;
- scale_factors.push_back(ui::SCALE_FACTOR_100P);
- scoped_set_supported_scale_factors_.reset(
- new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
-}
-
-RenderViewHostImplTestHarness::~RenderViewHostImplTestHarness() {
-}
-
-TestRenderViewHost* RenderViewHostImplTestHarness::test_rvh() {
- return static_cast<TestRenderViewHost*>(rvh());
-}
-
-TestRenderViewHost* RenderViewHostImplTestHarness::pending_test_rvh() {
- return static_cast<TestRenderViewHost*>(pending_rvh());
-}
-
-TestRenderViewHost* RenderViewHostImplTestHarness::active_test_rvh() {
- return static_cast<TestRenderViewHost*>(active_rvh());
-}
-
-TestWebContents* RenderViewHostImplTestHarness::contents() {
- return static_cast<TestWebContents*>(web_contents());
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h
deleted file mode 100644
index 97bcd6e703..0000000000
--- a/content/browser/renderer_host/test_render_view_host.h
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_
-#define CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "build/build_config.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/render_widget_host_view_base.h"
-#include "content/public/common/page_transition_types.h"
-#include "content/public/test/test_renderer_host.h"
-#include "ui/base/layout.h"
-#include "ui/gfx/vector2d_f.h"
-
-// This file provides a testing framework for mocking out the RenderProcessHost
-// layer. It allows you to test RenderViewHost, WebContentsImpl,
-// NavigationController, and other layers above that without running an actual
-// renderer process.
-//
-// To use, derive your test base class from RenderViewHostImplTestHarness.
-
-struct ViewHostMsg_FrameNavigate_Params;
-
-namespace gfx {
-class Rect;
-}
-
-namespace content {
-
-class SiteInstance;
-class TestWebContents;
-
-// Utility function to initialize ViewHostMsg_NavigateParams_Params
-// with given |page_id|, |url| and |transition_type|.
-void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
- int page_id,
- const GURL& url,
- PageTransition transition_type);
-
-// TestRenderViewHostView ------------------------------------------------------
-
-// Subclass the RenderViewHost's view so that we can call Show(), etc.,
-// without having side-effects.
-class TestRenderWidgetHostView : public RenderWidgetHostViewBase {
- public:
- explicit TestRenderWidgetHostView(RenderWidgetHost* rwh);
- virtual ~TestRenderWidgetHostView();
-
- // RenderWidgetHostView implementation.
- virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE {}
- virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
- virtual void SetSize(const gfx::Size& size) OVERRIDE {}
- virtual void SetBounds(const gfx::Rect& rect) OVERRIDE {}
- virtual gfx::NativeView GetNativeView() const OVERRIDE;
- virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
- virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
- virtual bool HasFocus() const OVERRIDE;
- virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
- virtual void Show() OVERRIDE;
- virtual void Hide() OVERRIDE;
- virtual bool IsShowing() OVERRIDE;
- virtual gfx::Rect GetViewBounds() const OVERRIDE;
-#if defined(OS_MACOSX)
- virtual void SetActive(bool active) OVERRIDE;
- virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE {}
- virtual void SetWindowVisibility(bool visible) OVERRIDE {}
- virtual void WindowFrameChanged() OVERRIDE {}
- virtual void ShowDefinitionForSelection() OVERRIDE {}
- virtual bool SupportsSpeech() const OVERRIDE;
- virtual void SpeakSelection() OVERRIDE;
- virtual bool IsSpeaking() const OVERRIDE;
- virtual void StopSpeaking() OVERRIDE;
-#endif // defined(OS_MACOSX)
-#if defined(TOOLKIT_GTK)
- virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
- virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
-#endif // defined(TOOLKIT_GTK)
- virtual void OnSwapCompositorFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
-
- // RenderWidgetHostViewPort implementation.
- virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
- const gfx::Rect& pos) OVERRIDE {}
- virtual void InitAsFullscreen(
- RenderWidgetHostView* reference_host_view) OVERRIDE {}
- virtual void WasShown() OVERRIDE {}
- virtual void WasHidden() OVERRIDE {}
- virtual void MovePluginWindows(
- const gfx::Vector2d& scroll_offset,
- const std::vector<WebPluginGeometry>& moves) OVERRIDE {}
- virtual void Focus() OVERRIDE {}
- virtual void Blur() OVERRIDE {}
- virtual void SetIsLoading(bool is_loading) OVERRIDE {}
- virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE {}
- virtual void TextInputTypeChanged(ui::TextInputType type,
- ui::TextInputMode input_mode,
- bool can_compose_inline) OVERRIDE {}
- virtual void ImeCancelComposition() OVERRIDE {}
-#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
- virtual void ImeCompositionRangeChanged(
- const gfx::Range& range,
- const std::vector<gfx::Rect>& character_bounds) OVERRIDE {}
-#endif
- virtual void DidUpdateBackingStore(
- const gfx::Rect& scroll_rect,
- const gfx::Vector2d& scroll_delta,
- const std::vector<gfx::Rect>& rects,
- const ui::LatencyInfo& latency_info) OVERRIDE {}
- virtual void RenderProcessGone(base::TerminationStatus status,
- int error_code) OVERRIDE;
- virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) { }
- virtual void Destroy() OVERRIDE;
- virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE {}
- virtual void SelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE {}
- virtual void ScrollOffsetChanged() OVERRIDE {}
- virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
- virtual void CopyFromCompositingSurface(
- const gfx::Rect& src_subrect,
- const gfx::Size& dst_size,
- const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE;
- virtual void CopyFromCompositingSurfaceToVideoFrame(
- const gfx::Rect& src_subrect,
- const scoped_refptr<media::VideoFrame>& target,
- const base::Callback<void(bool)>& callback) OVERRIDE;
- virtual bool CanCopyToVideoFrame() const OVERRIDE;
- virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
- virtual void AcceleratedSurfaceInitialized(int host_id,
- int route_id) OVERRIDE;
- virtual void AcceleratedSurfaceBuffersSwapped(
- const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
- int gpu_host_id) OVERRIDE;
- virtual void AcceleratedSurfacePostSubBuffer(
- const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
- int gpu_host_id) OVERRIDE;
- virtual void AcceleratedSurfaceSuspend() OVERRIDE;
- virtual void AcceleratedSurfaceRelease() OVERRIDE {}
- virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
-#if defined(OS_MACOSX)
- virtual void AboutToWaitForBackingStoreMsg() OVERRIDE;
- virtual bool PostProcessEventForPluginIme(
- const NativeWebKeyboardEvent& event) OVERRIDE;
-#elif defined(OS_ANDROID)
- virtual void ShowDisambiguationPopup(
- const gfx::Rect& target_rect,
- const SkBitmap& zoomed_bitmap) OVERRIDE {}
- virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE {}
-#elif defined(OS_WIN) && !defined(USE_AURA)
- virtual void WillWmDestroy() OVERRIDE;
-#endif
- virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE {}
- virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
- virtual void SetHasHorizontalScrollbar(
- bool has_horizontal_scrollbar) OVERRIDE { }
- virtual void SetScrollOffsetPinning(
- bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE { }
- virtual void OnAccessibilityEvents(
- const std::vector<AccessibilityHostMsg_EventParams>& params) OVERRIDE {}
- virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
-#if defined(OS_WIN) && !defined(USE_AURA)
- virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
-#endif
- virtual bool LockMouse() OVERRIDE;
- virtual void UnlockMouse() OVERRIDE;
-#if defined(OS_WIN) && defined(USE_AURA)
- virtual void SetParentNativeViewAccessible(
- gfx::NativeViewAccessible accessible_parent) OVERRIDE;
- virtual gfx::NativeViewId GetParentForWindowlessPlugin() const OVERRIDE;
-#endif
-
- bool is_showing() const { return is_showing_; }
- bool did_swap_compositor_frame() const { return did_swap_compositor_frame_; }
-
- protected:
- RenderWidgetHostImpl* rwh_;
-
- private:
- bool is_showing_;
- bool did_swap_compositor_frame_;
-};
-
-#if defined(COMPILER_MSVC)
-// See comment for same warning on RenderViewHostImpl.
-#pragma warning(push)
-#pragma warning(disable: 4250)
-#endif
-
-// TestRenderViewHost ----------------------------------------------------------
-
-// TODO(brettw) this should use a TestWebContents which should be generalized
-// from the WebContentsImpl test. We will probably also need that class' version
-// of CreateRenderViewForRenderManager when more complicated tests start using
-// this.
-//
-// Note that users outside of content must use this class by getting
-// the separate RenderViewHostTester interface via
-// RenderViewHostTester::For(rvh) on the RenderViewHost they want to
-// drive tests on.
-//
-// Users within content may directly static_cast from a
-// RenderViewHost* to a TestRenderViewHost*.
-//
-// The reasons we do it this way rather than extending the parallel
-// inheritance hierarchy we have for RenderWidgetHost/RenderViewHost
-// vs. RenderWidgetHostImpl/RenderViewHostImpl are:
-//
-// a) Extending the parallel class hierarchy further would require
-// more classes to use virtual inheritance. This is a complexity that
-// is better to avoid, especially when it would be introduced in the
-// production code solely to facilitate testing code.
-//
-// b) While users outside of content only need to drive tests on a
-// RenderViewHost, content needs a test version of the full
-// RenderViewHostImpl so that it can test all methods on that concrete
-// class (e.g. overriding a method such as
-// RenderViewHostImpl::CreateRenderView). This would have complicated
-// the dual class hierarchy even further.
-//
-// The reason we do it this way instead of using composition is
-// similar to (b) above, essentially it gets very tricky. By using
-// the split interface we avoid complexity within content and maintain
-// reasonable utility for embedders.
-class TestRenderViewHost
- : public RenderViewHostImpl,
- public RenderViewHostTester {
- public:
- TestRenderViewHost(SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- RenderWidgetHostDelegate* widget_delegate,
- int routing_id,
- int main_frame_routing_id,
- bool swapped_out);
- virtual ~TestRenderViewHost();
-
- // RenderViewHostTester implementation. Note that CreateRenderView
- // is not specified since it is synonymous with the one from
- // RenderViewHostImpl, see below.
- virtual void SendNavigate(int page_id, const GURL& url) OVERRIDE;
- virtual void SendFailedNavigate(int page_id, const GURL& url) OVERRIDE;
- virtual void SendNavigateWithTransition(int page_id, const GURL& url,
- PageTransition transition) OVERRIDE;
- virtual void SendShouldCloseACK(bool proceed) OVERRIDE;
- virtual void SetContentsMimeType(const std::string& mime_type) OVERRIDE;
- virtual void SimulateSwapOutACK() OVERRIDE;
- virtual void SimulateWasHidden() OVERRIDE;
- virtual void SimulateWasShown() OVERRIDE;
-
- // Calls OnNavigate on the RenderViewHost with the given information,
- // including a custom original request URL. Sets the rest of the
- // parameters in the message to the "typical" values. This is a helper
- // function for simulating the most common types of loads.
- void SendNavigateWithOriginalRequestURL(
- int page_id, const GURL& url, const GURL& original_request_url);
-
- void SendNavigateWithFile(
- int page_id, const GURL& url, const base::FilePath& file_path);
-
- void TestOnUpdateStateWithFile(
- int process_id, const base::FilePath& file_path);
-
- void TestOnStartDragging(const DropData& drop_data);
-
- // If set, *delete_counter is incremented when this object destructs.
- void set_delete_counter(int* delete_counter) {
- delete_counter_ = delete_counter;
- }
-
- // Sets whether the RenderView currently exists or not. This controls the
- // return value from IsRenderViewLive, which the rest of the system uses to
- // check whether the RenderView has crashed or not.
- void set_render_view_created(bool created) {
- render_view_created_ = created;
- }
-
- // Returns whether the RenderViewHost is currently waiting to hear the result
- // of a before unload handler from the renderer.
- bool is_waiting_for_beforeunload_ack() const {
- return is_waiting_for_beforeunload_ack_;
- }
-
- // Returns whether the RenderViewHost is currently waiting to hear the result
- // of an unload handler from the renderer.
- bool is_waiting_for_unload_ack() const {
- return is_waiting_for_unload_ack_;
- }
-
- // Sets whether the RenderViewHost is currently swapped out, and thus
- // filtering messages from the renderer.
- void set_is_swapped_out(bool is_swapped_out) {
- is_swapped_out_ = is_swapped_out;
- }
-
- // If set, navigations will appear to have loaded through a proxy
- // (ViewHostMsg_FrameNavigte_Params::was_fetched_via_proxy).
- // False by default.
- void set_simulate_fetch_via_proxy(bool proxy);
-
- // If set, navigations will appear to have cleared the history list in the
- // RenderView (ViewHostMsg_FrameNavigate_Params::history_list_was_cleared).
- // False by default.
- void set_simulate_history_list_was_cleared(bool cleared);
-
- // The opener route id passed to CreateRenderView().
- int opener_route_id() const { return opener_route_id_; }
-
- // RenderViewHost overrides --------------------------------------------------
-
- virtual bool CreateRenderView(const string16& frame_name,
- int opener_route_id,
- int32 max_page_id) OVERRIDE;
- virtual bool IsRenderViewLive() const OVERRIDE;
-
- private:
- FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, FilterNavigate);
-
- void SendNavigateWithTransitionAndResponseCode(int page_id,
- const GURL& url,
- PageTransition transition,
- int response_code);
-
- // Calls OnNavigate on the RenderViewHost with the given information.
- // Sets the rest of the parameters in the message to the "typical" values.
- // This is a helper function for simulating the most common types of loads.
- void SendNavigateWithParameters(
- int page_id,
- const GURL& url,
- PageTransition transition,
- const GURL& original_request_url,
- int response_code,
- const base::FilePath* file_path_for_history_item);
-
- // Tracks if the caller thinks if it created the RenderView. This is so we can
- // respond to IsRenderViewLive appropriately.
- bool render_view_created_;
-
- // See set_delete_counter() above. May be NULL.
- int* delete_counter_;
-
- // See set_simulate_fetch_via_proxy() above.
- bool simulate_fetch_via_proxy_;
-
- // See set_simulate_history_list_was_cleared() above.
- bool simulate_history_list_was_cleared_;
-
- // See SetContentsMimeType() above.
- std::string contents_mime_type_;
-
- // See opener_route_id() above.
- int opener_route_id_;
-
- DISALLOW_COPY_AND_ASSIGN(TestRenderViewHost);
-};
-
-#if defined(COMPILER_MSVC)
-#pragma warning(pop)
-#endif
-
-// Adds methods to get straight at the impl classes.
-class RenderViewHostImplTestHarness : public RenderViewHostTestHarness {
- public:
- RenderViewHostImplTestHarness();
- virtual ~RenderViewHostImplTestHarness();
-
- TestRenderViewHost* test_rvh();
- TestRenderViewHost* pending_test_rvh();
- TestRenderViewHost* active_test_rvh();
- TestWebContents* contents();
-
- private:
- typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
- ScopedSetSupportedScaleFactors;
- ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
- DISALLOW_COPY_AND_ASSIGN(RenderViewHostImplTestHarness);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_
diff --git a/content/browser/renderer_host/web_input_event_aura.cc b/content/browser/renderer_host/web_input_event_aura.cc
index 5127c07fb1..f35d37740e 100644
--- a/content/browser/renderer_host/web_input_event_aura.cc
+++ b/content/browser/renderer_host/web_input_event_aura.cc
@@ -9,6 +9,10 @@
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
+#if defined(USE_OZONE)
+#include "ui/events/keycodes/keyboard_code_conversion.h"
+#endif
+
namespace content {
#if defined(USE_X11) || defined(USE_OZONE)
@@ -101,7 +105,9 @@ blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
if (webkit_event.windowsKeyCode == ui::VKEY_RETURN)
webkit_event.unmodifiedText[0] = '\r';
else
- webkit_event.unmodifiedText[0] = character;
+ webkit_event.unmodifiedText[0] = ui::GetCharacterFromKeyCode(
+ ui::KeyboardCodeFromNative(native_event),
+ ui::EventFlagsFromNative(native_event));
if (webkit_event.modifiers & blink::WebInputEvent::ControlKey) {
webkit_event.text[0] =
diff --git a/content/browser/renderer_host/webmenurunner_mac.mm b/content/browser/renderer_host/webmenurunner_mac.mm
index a81d2c9e2f..bb33a007aa 100644
--- a/content/browser/renderer_host/webmenurunner_mac.mm
+++ b/content/browser/renderer_host/webmenurunner_mac.mm
@@ -82,6 +82,14 @@
[[NSAttributedString alloc] initWithString:title attributes:attrs]);
[menuItem setAttributedTitle:attrTitle];
+ // We set the title as well as the attributed title here. The attributed title
+ // will be displayed in the menu, but typeahead will use the non-attributed
+ // string that doesn't contain any leading or trailing whitespace. This is
+ // what Apple uses in WebKit as well:
+ // http://trac.webkit.org/browser/trunk/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm#L90
+ NSCharacterSet* whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
+ [menuItem setTitle:[title stringByTrimmingCharactersInSet:whitespaceSet]];
+
[menuItem setTag:[menu_ numberOfItems] - 1];
}
diff --git a/content/browser/resource_context_impl.cc b/content/browser/resource_context_impl.cc
index c026d936ac..c2f22073e0 100644
--- a/content/browser/resource_context_impl.cc
+++ b/content/browser/resource_context_impl.cc
@@ -55,6 +55,10 @@ ResourceContext::~ResourceContext() {
DetachUserDataThread();
}
+std::string ResourceContext::GetMediaDeviceIDSalt() {
+ return std::string();
+}
+
scoped_ptr<net::ClientCertStore> ResourceContext::CreateClientCertStore() {
return scoped_ptr<net::ClientCertStore>();
}
diff --git a/content/browser/resources/gpu/info_view.js b/content/browser/resources/gpu/info_view.js
index 13afa4af02..e736d8e49a 100644
--- a/content/browser/resources/gpu/info_view.js
+++ b/content/browser/resources/gpu/info_view.js
@@ -92,6 +92,7 @@ cr.define('gpu', function() {
'flash_stage3d_baseline': 'Flash Stage3D Baseline profile',
'texture_sharing': 'Texture Sharing',
'video_decode': 'Video Decode',
+ 'video_encode': 'Video Encode',
'video': 'Video',
// GPU Switching
'gpu_switching': 'GPU Switching',
diff --git a/content/browser/resources/media/dump_creator.js b/content/browser/resources/media/dump_creator.js
index 5daddabc61..af17cf3a4e 100644
--- a/content/browser/resources/media/dump_creator.js
+++ b/content/browser/resources/media/dump_creator.js
@@ -55,12 +55,12 @@ var DumpCreator = (function() {
this.root_.appendChild(content);
content.innerHTML = '<button disabled></button> Status: <span></span>' +
- '<div><form><button>' +
+ '<div><a><button>' +
'Download the PeerConnection updates and stats data' +
- '</button></form></div>';
+ '</button></a></div>';
content.getElementsByTagName('button')[0].addEventListener(
'click', this.onRtpToggled_.bind(this));
- content.getElementsByTagName('button')[1].addEventListener(
+ content.getElementsByTagName('a')[0].addEventListener(
'click', this.onDownloadData_.bind(this));
this.updateDisplay_();
@@ -77,8 +77,8 @@ var DumpCreator = (function() {
new Blob([JSON.stringify(peerConnectionDataStore, null, ' ')],
{type: 'octet/stream'});
var URL = window.webkitURL.createObjectURL(textBlob);
- this.root_.getElementsByTagName('form')[0].action = URL;
- // The default action of the button will submit the form.
+ this.root_.getElementsByTagName('a')[0].href = URL;
+ // The default action of the anchor will download the URL.
},
/**
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 2eb7b51885..dacc1e6efd 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -3,11 +3,19 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/containers/hash_tables.h"
+#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
+#include "content/browser/dom_storage/session_storage_namespace_impl.h"
+#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/view_messages.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
@@ -15,6 +23,61 @@
namespace content {
+namespace {
+
+// This is a helper function for the tests which attempt to create a
+// duplicate RenderViewHost or RenderWidgetHost. It tries to create two objects
+// with the same process and routing ids, which causes a collision.
+// It creates a couple of windows in process 1, which causes a few routing ids
+// to be allocated. Then a cross-process navigation is initiated, which causes a
+// new process 2 to be created and have a pending RenderViewHost for it. The
+// routing id of the RenderViewHost which is target for a duplicate is set
+// into |target_routing_id| and the pending RenderViewHost which is used for
+// the attempt is the return value.
+RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell,
+ int* target_routing_id) {
+ GURL foo("http://foo.com/files/simple_page.html");
+
+ // Start off with initial navigation, so we get the first process allocated.
+ NavigateToURL(shell, foo);
+
+ // Open another window, so we generate some more routing ids.
+ ShellAddedObserver shell2_observer;
+ EXPECT_TRUE(ExecuteScript(
+ shell->web_contents(), "window.open(document.URL + '#2');"));
+ Shell* shell2 = shell2_observer.GetShell();
+
+ // The new window must be in the same process, but have a new routing id.
+ EXPECT_EQ(shell->web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
+ shell2->web_contents()->GetRenderViewHost()->GetProcess()->GetID());
+ *target_routing_id =
+ shell2->web_contents()->GetRenderViewHost()->GetRoutingID();
+ EXPECT_NE(*target_routing_id,
+ shell->web_contents()->GetRenderViewHost()->GetRoutingID());
+
+ // Now, simulate a link click coming from the renderer.
+ GURL extension_url("https://bar.com/files/simple_page.html");
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents());
+ wc->RequestOpenURL(
+ shell->web_contents()->GetRenderViewHost(), extension_url,
+ Referrer(), CURRENT_TAB, wc->GetFrameTree()->root()->frame_id(),
+ false, true);
+
+ // Since the navigation above requires a cross-process swap, there will be a
+ // pending RenderViewHost. Ensure it exists and is in a different process
+ // than the initial page.
+ RenderViewHostImpl* pending_rvh =
+ wc->GetRenderManagerForTesting()->pending_render_view_host();
+ EXPECT_TRUE(pending_rvh != NULL);
+ EXPECT_NE(shell->web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
+ pending_rvh->GetProcess()->GetID());
+
+ return pending_rvh;
+}
+
+} // namespace
+
+
// The goal of these tests will be to "simulate" exploited renderer processes,
// which can send arbitrary IPC messages and confuse browser process internal
// state, leading to security bugs. We are trying to verify that the browser
@@ -52,4 +115,54 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, SetWebUIProperty) {
terminated.Wait();
}
+// This is a test for crbug.com/312016 attempting to create duplicate
+// RenderViewHosts. SetupForDuplicateHosts sets up this test case and leaves
+// it in a state with pending RenderViewHost. Before the commit of the new
+// pending RenderViewHost, this test case creates a new window through the new
+// process.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ AttemptDuplicateRenderViewHost) {
+ int duplicate_routing_id = MSG_ROUTING_NONE;
+ RenderViewHostImpl* pending_rvh =
+ PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
+ EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);
+
+ // Since this test executes on the UI thread and hopping threads might cause
+ // different timing in the test, let's simulate a CreateNewWindow call coming
+ // from the IO thread.
+ ViewHostMsg_CreateWindow_Params params;
+ DOMStorageContextWrapper* dom_storage_context =
+ static_cast<DOMStorageContextWrapper*>(
+ BrowserContext::GetStoragePartition(
+ shell()->web_contents()->GetBrowserContext(),
+ pending_rvh->GetSiteInstance())->GetDOMStorageContext());
+ SessionStorageNamespaceImpl* session_storage =
+ new SessionStorageNamespaceImpl(dom_storage_context);
+ // Cause a deliberate collision in routing ids.
+ int main_frame_routing_id = duplicate_routing_id + 1;
+ pending_rvh->CreateNewWindow(
+ duplicate_routing_id, main_frame_routing_id, params, session_storage);
+
+ // If the above operation doesn't cause a crash, the test has succeeded!
}
+
+// This is a test for crbug.com/312016. It tries to create two RenderWidgetHosts
+// with the same process and routing ids, which causes a collision. It is almost
+// identical to the AttemptDuplicateRenderViewHost test case.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ AttemptDuplicateRenderWidgetHost) {
+ int duplicate_routing_id = MSG_ROUTING_NONE;
+ RenderViewHostImpl* pending_rvh =
+ PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
+ EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);
+
+ // Since this test executes on the UI thread and hopping threads might cause
+ // different timing in the test, let's simulate a CreateNewWidget call coming
+ // from the IO thread. Use the existing window routing id to cause a
+ // deliberate collision.
+ pending_rvh->CreateNewWidget(duplicate_routing_id, blink::WebPopupTypeSelect);
+
+ // If the above operation doesn't crash, the test has succeeded!
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
new file mode 100644
index 0000000000..0799884598
--- /dev/null
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -0,0 +1,99 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/embedded_worker_instance.h"
+
+#include "content/browser/service_worker/embedded_worker_registry.h"
+#include "url/gurl.h"
+
+namespace content {
+
+EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
+ registry_->RemoveWorker(embedded_worker_id_);
+}
+
+bool EmbeddedWorkerInstance::Start(
+ int64 service_worker_version_id,
+ const GURL& script_url) {
+ DCHECK(status_ == STOPPED);
+ if (!ChooseProcess())
+ return false;
+ status_ = STARTING;
+ bool success = registry_->StartWorker(
+ process_id_,
+ embedded_worker_id_,
+ service_worker_version_id,
+ script_url);
+ if (!success) {
+ status_ = STOPPED;
+ process_id_ = -1;
+ }
+ return success;
+}
+
+bool EmbeddedWorkerInstance::Stop() {
+ DCHECK(status_ == STARTING || status_ == RUNNING);
+ const bool success = registry_->StopWorker(process_id_, embedded_worker_id_);
+ if (success)
+ status_ = STOPPING;
+ return success;
+}
+
+void EmbeddedWorkerInstance::AddProcessReference(int process_id) {
+ ProcessRefMap::iterator found = process_refs_.find(process_id);
+ if (found == process_refs_.end())
+ found = process_refs_.insert(std::make_pair(process_id, 0)).first;
+ ++found->second;
+}
+
+void EmbeddedWorkerInstance::ReleaseProcessReference(int process_id) {
+ ProcessRefMap::iterator found = process_refs_.find(process_id);
+ if (found == process_refs_.end()) {
+ NOTREACHED() << "Releasing unknown process ref " << process_id;
+ return;
+ }
+ if (--found->second == 0)
+ process_refs_.erase(found);
+}
+
+EmbeddedWorkerInstance::EmbeddedWorkerInstance(
+ EmbeddedWorkerRegistry* registry,
+ int embedded_worker_id)
+ : registry_(registry),
+ embedded_worker_id_(embedded_worker_id),
+ status_(STOPPED),
+ process_id_(-1),
+ thread_id_(-1) {
+}
+
+void EmbeddedWorkerInstance::OnStarted(int thread_id) {
+ DCHECK(status_ == STARTING);
+ status_ = RUNNING;
+ thread_id_ = thread_id;
+}
+
+void EmbeddedWorkerInstance::OnStopped() {
+ status_ = STOPPED;
+ process_id_ = -1;
+ thread_id_ = -1;
+}
+
+bool EmbeddedWorkerInstance::ChooseProcess() {
+ DCHECK_EQ(-1, process_id_);
+ // Naive implementation; chooses a process which has the biggest number of
+ // associated providers (so that hopefully likely live longer).
+ ProcessRefMap::iterator max_ref_iter = process_refs_.end();
+ for (ProcessRefMap::iterator iter = process_refs_.begin();
+ iter != process_refs_.end(); ++iter) {
+ if (max_ref_iter == process_refs_.end() ||
+ max_ref_iter->second < iter->second)
+ max_ref_iter = iter;
+ }
+ if (max_ref_iter == process_refs_.end())
+ return false;
+ process_id_ = max_ref_iter->first;
+ return true;
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
new file mode 100644
index 0000000000..fb0fe19bb6
--- /dev/null
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -0,0 +1,102 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/gtest_prod_util.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
+
+class GURL;
+
+namespace content {
+
+class EmbeddedWorkerRegistry;
+
+// This gives an interface to control one EmbeddedWorker instance, which
+// may be 'in-waiting' or running in one of the child processes added by
+// AddProcessReference().
+class CONTENT_EXPORT EmbeddedWorkerInstance {
+ public:
+ enum Status {
+ STOPPED,
+ STARTING,
+ RUNNING,
+ STOPPING,
+ };
+
+ ~EmbeddedWorkerInstance();
+
+ // Starts the worker. It is invalid to call this when the worker is
+ // not in STOPPED status.
+ // This returns false if starting a worker fails immediately, e.g. when
+ // IPC couldn't be sent to the worker or no process was available.
+ bool Start(int64 service_worker_version_id,
+ const GURL& script_url);
+
+ // Stops the worker. It is invalid to call this when the worker is
+ // not in STARTING or RUNNING status.
+ // This returns false if stopping a worker fails immediately, e.g. when
+ // IPC couldn't be sent to the worker.
+ bool Stop();
+
+ // Add or remove |process_id| to the internal process set where this
+ // worker can be started.
+ void AddProcessReference(int process_id);
+ void ReleaseProcessReference(int process_id);
+
+ int embedded_worker_id() const { return embedded_worker_id_; }
+ Status status() const { return status_; }
+ int process_id() const { return process_id_; }
+ int thread_id() const { return thread_id_; }
+
+ private:
+ friend class EmbeddedWorkerRegistry;
+ FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
+
+ typedef std::map<int, int> ProcessRefMap;
+
+ // Constructor is called via EmbeddedWorkerRegistry::CreateWorker().
+ // This instance holds a ref of |registry|.
+ EmbeddedWorkerInstance(EmbeddedWorkerRegistry* registry,
+ int embedded_worker_id);
+
+ // Called back from Registry when the worker instance has ack'ed that
+ // its WorkerGlobalScope is actually started on |thread_id| in the
+ // child process.
+ // This will change the internal status from STARTING to RUNNING.
+ void OnStarted(int thread_id);
+
+ // Called back from Registry when the worker instance has ack'ed that
+ // its WorkerGlobalScope is actually stopped in the child process.
+ // This will change the internal status from STARTING or RUNNING to
+ // STOPPED.
+ void OnStopped();
+
+ // Chooses a process to start this worker and populate process_id_.
+ // Returns false when no process is available.
+ bool ChooseProcess();
+
+ scoped_refptr<EmbeddedWorkerRegistry> registry_;
+ const int embedded_worker_id_;
+ Status status_;
+
+ // Current running information. -1 indicates the worker is not running.
+ int process_id_;
+ int thread_id_;
+
+ ProcessRefMap process_refs_;
+
+ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstance);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
new file mode 100644
index 0000000000..45b2f29dc7
--- /dev/null
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -0,0 +1,137 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/stl_util.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/embedded_worker_registry.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/common/service_worker_messages.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sender.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+typedef std::vector<IPC::Message*> MessageList;
+
+class FakeSender : public IPC::Sender {
+ public:
+ FakeSender() {}
+ virtual ~FakeSender() {
+ STLDeleteContainerPointers(sent_messages_.begin(), sent_messages_.end());
+ }
+
+ // IPC::Sender implementation.
+ virtual bool Send(IPC::Message* message) OVERRIDE {
+ sent_messages_.push_back(message);
+ return true;
+ }
+
+ const MessageList& sent_messages() { return sent_messages_; }
+
+ private:
+ MessageList sent_messages_;
+ DISALLOW_COPY_AND_ASSIGN(FakeSender);
+};
+
+} // namespace
+
+class EmbeddedWorkerInstanceTest : public testing::Test {
+ protected:
+ EmbeddedWorkerInstanceTest()
+ : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
+
+ virtual void SetUp() OVERRIDE {
+ context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL));
+ }
+
+ virtual void TearDown() OVERRIDE {
+ context_.reset();
+ }
+
+ EmbeddedWorkerRegistry* embedded_worker_registry() {
+ DCHECK(context_);
+ return context_->embedded_worker_registry();
+ }
+
+ TestBrowserThreadBundle thread_bundle_;
+ scoped_ptr<ServiceWorkerContextCore> context_;
+
+ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest);
+};
+
+TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
+ scoped_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker();
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+
+ FakeSender fake_sender;
+ const int process_id = 11;
+ const int thread_id = 33;
+ const int64 service_worker_version_id = 55L;
+ const GURL url("http://example.com/worker.js");
+
+ // This fails as we have no available process yet.
+ EXPECT_FALSE(worker->Start(service_worker_version_id, url));
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+
+ // Simulate adding one process to the worker.
+ worker->AddProcessReference(process_id);
+ embedded_worker_registry()->AddChildProcessSender(process_id, &fake_sender);
+
+ // Start should succeed.
+ EXPECT_TRUE(worker->Start(service_worker_version_id, url));
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status());
+
+ // Simulate an upcall from embedded worker to notify that it's started.
+ worker->OnStarted(thread_id);
+ EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status());
+ EXPECT_EQ(process_id, worker->process_id());
+ EXPECT_EQ(thread_id, worker->thread_id());
+
+ // Stop the worker.
+ EXPECT_TRUE(worker->Stop());
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, worker->status());
+
+ // Simulate an upcall from embedded worker to notify that it's stopped.
+ worker->OnStopped();
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+
+ // Verify that we've sent two messages to start and terminate the worker.
+ const MessageList& messages = fake_sender.sent_messages();
+ ASSERT_EQ(2U, messages.size());
+ ASSERT_EQ(ServiceWorkerMsg_StartWorker::ID, messages[0]->type());
+ ASSERT_EQ(ServiceWorkerMsg_TerminateWorker::ID, messages[1]->type());
+}
+
+TEST_F(EmbeddedWorkerInstanceTest, ChooseProcess) {
+ scoped_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker();
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
+
+ FakeSender fake_sender;
+
+ // Simulate adding processes to the worker.
+ // Process 1 has 1 ref, 2 has 2 refs and 3 has 3 refs.
+ worker->AddProcessReference(1);
+ worker->AddProcessReference(2);
+ worker->AddProcessReference(2);
+ worker->AddProcessReference(3);
+ worker->AddProcessReference(3);
+ worker->AddProcessReference(3);
+ embedded_worker_registry()->AddChildProcessSender(1, &fake_sender);
+ embedded_worker_registry()->AddChildProcessSender(2, &fake_sender);
+ embedded_worker_registry()->AddChildProcessSender(3, &fake_sender);
+
+ // Process 3 has the biggest # of references and it should be chosen.
+ EXPECT_TRUE(worker->Start(1L, GURL("http://example.com/worker.js")));
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status());
+ EXPECT_EQ(3, worker->process_id());
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc
new file mode 100644
index 0000000000..f8f0fbe7d5
--- /dev/null
+++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -0,0 +1,70 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/embedded_worker_registry.h"
+
+#include "base/stl_util.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/common/service_worker_messages.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_sender.h"
+
+namespace content {
+
+EmbeddedWorkerRegistry::EmbeddedWorkerRegistry(
+ base::WeakPtr<ServiceWorkerContextCore> context)
+ : context_(context),
+ next_embedded_worker_id_(0) {}
+
+scoped_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker() {
+ scoped_ptr<EmbeddedWorkerInstance> worker(
+ new EmbeddedWorkerInstance(this, next_embedded_worker_id_));
+ worker_map_[next_embedded_worker_id_++] = worker.get();
+ return worker.Pass();
+}
+
+void EmbeddedWorkerRegistry::RemoveWorker(int embedded_worker_id) {
+ DCHECK(ContainsKey(worker_map_, embedded_worker_id));
+ worker_map_.erase(embedded_worker_id);
+}
+
+bool EmbeddedWorkerRegistry::StartWorker(
+ int process_id,
+ int embedded_worker_id,
+ int64 service_worker_version_id,
+ const GURL& script_url) {
+ return Send(process_id,
+ new ServiceWorkerMsg_StartWorker(embedded_worker_id,
+ service_worker_version_id,
+ script_url));
+}
+
+bool EmbeddedWorkerRegistry::StopWorker(int process_id,
+ int embedded_worker_id) {
+ return Send(process_id,
+ new ServiceWorkerMsg_TerminateWorker(embedded_worker_id));
+}
+
+void EmbeddedWorkerRegistry::AddChildProcessSender(
+ int process_id, IPC::Sender* sender) {
+ process_sender_map_[process_id] = sender;
+}
+
+void EmbeddedWorkerRegistry::RemoveChildProcessSender(int process_id) {
+ process_sender_map_.erase(process_id);
+}
+
+EmbeddedWorkerRegistry::~EmbeddedWorkerRegistry() {}
+
+bool EmbeddedWorkerRegistry::Send(int process_id, IPC::Message* message) {
+ if (!context_)
+ return false;
+ ProcessToSenderMap::iterator found = process_sender_map_.find(process_id);
+ if (found == process_sender_map_.end())
+ return false;
+ return found->second->Send(message);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h
new file mode 100644
index 0000000000..8860e374b5
--- /dev/null
+++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -0,0 +1,77 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_REGISTRY_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_REGISTRY_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+
+class GURL;
+
+namespace IPC {
+class Message;
+class Sender;
+}
+
+namespace content {
+
+class EmbeddedWorkerInstance;
+class ServiceWorkerContextCore;
+
+// Acts as a thin stub between MessageFilter and each EmbeddedWorkerInstance,
+// which sends/receives messages to/from each EmbeddedWorker in child process.
+//
+// Hangs off ServiceWorkerContextCore (its reference is also held by each
+// EmbeddedWorkerInstance). Operated only on IO thread.
+class CONTENT_EXPORT EmbeddedWorkerRegistry
+ : public NON_EXPORTED_BASE(base::RefCounted<EmbeddedWorkerRegistry>) {
+ public:
+ explicit EmbeddedWorkerRegistry(
+ base::WeakPtr<ServiceWorkerContextCore> context);
+
+ // Creates and removes a new worker instance entry for bookkeeping.
+ // This doesn't actually start or stop the worker.
+ scoped_ptr<EmbeddedWorkerInstance> CreateWorker();
+ void RemoveWorker(int embedded_worker_id);
+
+ // Called from EmbeddedWorkerInstance, relayed to the child process.
+ bool StartWorker(int process_id,
+ int embedded_worker_id,
+ int64 service_worker_version_id,
+ const GURL& script_url);
+ bool StopWorker(int process_id,
+ int embedded_worker_id);
+
+ // Keeps a map from process_id to sender information.
+ void AddChildProcessSender(int process_id, IPC::Sender* sender);
+ void RemoveChildProcessSender(int process_id);
+
+ private:
+ friend class base::RefCounted<EmbeddedWorkerRegistry>;
+
+ ~EmbeddedWorkerRegistry();
+ bool Send(int process_id, IPC::Message* message);
+
+ typedef std::map<int, EmbeddedWorkerInstance*> WorkerInstanceMap;
+ typedef std::map<int, IPC::Sender*> ProcessToSenderMap;
+
+ base::WeakPtr<ServiceWorkerContextCore> context_;
+
+ WorkerInstanceMap worker_map_;
+ ProcessToSenderMap process_sender_map_;
+
+ int next_embedded_worker_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerRegistry);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_REGISTRY_H_
diff --git a/content/browser/service_worker/service_worker_context.h b/content/browser/service_worker/service_worker_context.h
index ce8bad90c1..d9f51f3165 100644
--- a/content/browser/service_worker/service_worker_context.h
+++ b/content/browser/service_worker/service_worker_context.h
@@ -5,18 +5,22 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_H_
+#include "base/basictypes.h"
+
namespace content {
// Represents the per-BrowserContext ServiceWorker data.
class ServiceWorkerContext {
public:
-
// TODO(michaeln): This class is a place holder for content/public api
// which will come later. Promote this class when we get there.
protected:
ServiceWorkerContext() {}
virtual ~ServiceWorkerContext() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContext);
};
} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 22ae500705..8d1e7a8796 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -6,29 +6,25 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/strings/string_util.h"
+#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_register_job.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_storage.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
-#include "webkit/browser/quota/quota_manager.h"
+#include "url/gurl.h"
namespace content {
-namespace {
-
-const base::FilePath::CharType kServiceWorkerDirectory[] =
- FILE_PATH_LITERAL("ServiceWorker");
-
-} // namespace
-
ServiceWorkerContextCore::ServiceWorkerContextCore(
- const base::FilePath& user_data_directory,
+ const base::FilePath& path,
quota::QuotaManagerProxy* quota_manager_proxy)
- : quota_manager_proxy_(quota_manager_proxy) {
- if (!user_data_directory.empty())
- path_ = user_data_directory.Append(kServiceWorkerDirectory);
-}
+ : storage_(new ServiceWorkerStorage(path, quota_manager_proxy)),
+ embedded_worker_registry_(new EmbeddedWorkerRegistry(AsWeakPtr())) {}
-ServiceWorkerContextCore::~ServiceWorkerContextCore() {
-}
+ServiceWorkerContextCore::~ServiceWorkerContextCore() {}
ServiceWorkerProviderHost* ServiceWorkerContextCore::GetProviderHost(
int process_id, int provider_id) {
@@ -67,4 +63,51 @@ bool ServiceWorkerContextCore::IsEnabled() {
switches::kEnableServiceWorker);
}
+void ServiceWorkerContextCore::RegisterServiceWorker(
+ const GURL& pattern,
+ const GURL& script_url,
+ const RegistrationCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ storage_->Register(pattern,
+ script_url,
+ base::Bind(&ServiceWorkerContextCore::RegistrationComplete,
+ AsWeakPtr(),
+ callback));
+}
+
+void ServiceWorkerContextCore::UnregisterServiceWorker(
+ const GURL& pattern,
+ const UnregistrationCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ storage_->Unregister(
+ pattern,
+ base::Bind(&ServiceWorkerContextCore::UnregistrationComplete,
+ AsWeakPtr(),
+ callback));
+}
+
+void ServiceWorkerContextCore::RegistrationComplete(
+ const ServiceWorkerContextCore::RegistrationCallback& callback,
+ ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ if (status != REGISTRATION_OK) {
+ DCHECK(!registration);
+ callback.Run(status, -1L);
+ }
+
+ callback.Run(status, registration->id());
+}
+
+void ServiceWorkerContextCore::UnregistrationComplete(
+ const UnregistrationCallback& callback,
+ ServiceWorkerRegistrationStatus status) {
+ // Unregistering a non-existent registration is a no-op.
+ if (status == REGISTRATION_OK || status == REGISTRATION_NOT_FOUND)
+ callback.Run(REGISTRATION_OK);
+ else
+ callback.Run(status);
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index 8d6f44250d..0351c2e74e 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -5,13 +5,20 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
+#include <map>
+
+#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/id_map.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_registration_status.h"
+#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
+class GURL;
+
namespace base {
class FilePath;
}
@@ -22,7 +29,10 @@ class QuotaManagerProxy;
namespace content {
+class EmbeddedWorkerRegistry;
class ServiceWorkerProviderHost;
+class ServiceWorkerRegistration;
+class ServiceWorkerStorage;
// This class manages data associated with service workers.
// The class is single threaded and should only be used on the IO thread.
@@ -33,11 +43,20 @@ class CONTENT_EXPORT ServiceWorkerContextCore
: NON_EXPORTED_BASE(
public base::SupportsWeakPtr<ServiceWorkerContextCore>) {
public:
- // Given an empty |user_data_directory|, nothing will be stored on disk.
+ typedef base::Callback<void(ServiceWorkerRegistrationStatus status,
+ int64 registration_id)> RegistrationCallback;
+ typedef base::Callback<
+ void(ServiceWorkerRegistrationStatus status)> UnregistrationCallback;
+
+ // This is owned by the StoragePartition, which will supply it with
+ // the local path on disk. Given an empty |user_data_directory|,
+ // nothing will be stored on disk.
ServiceWorkerContextCore(const base::FilePath& user_data_directory,
quota::QuotaManagerProxy* quota_manager_proxy);
~ServiceWorkerContextCore();
+ ServiceWorkerStorage* storage() { return storage_.get(); }
+
// The context class owns the set of ProviderHosts.
ServiceWorkerProviderHost* GetProviderHost(int process_id, int provider_id);
void AddProviderHost(scoped_ptr<ServiceWorkerProviderHost> provider_host);
@@ -47,6 +66,19 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// Checks the cmdline flag.
bool IsEnabled();
+ // The callback will be called on the IO thread.
+ void RegisterServiceWorker(const GURL& pattern,
+ const GURL& script_url,
+ const RegistrationCallback& callback);
+
+ // The callback will be called on the IO thread.
+ void UnregisterServiceWorker(const GURL& pattern,
+ const UnregistrationCallback& callback);
+
+ EmbeddedWorkerRegistry* embedded_worker_registry() {
+ return embedded_worker_registry_.get();
+ }
+
private:
typedef IDMap<ServiceWorkerProviderHost, IDMapOwnPointer> ProviderMap;
typedef IDMap<ProviderMap, IDMapOwnPointer> ProcessToProviderMap;
@@ -55,9 +87,18 @@ class CONTENT_EXPORT ServiceWorkerContextCore
return providers_.Lookup(process_id);
}
+ void RegistrationComplete(
+ const RegistrationCallback& callback,
+ ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+ void UnregistrationComplete(const UnregistrationCallback& callback,
+ ServiceWorkerRegistrationStatus status);
+
ProcessToProviderMap providers_;
- scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
- base::FilePath path_;
+ scoped_ptr<ServiceWorkerStorage> storage_;
+ scoped_refptr<EmbeddedWorkerRegistry> embedded_worker_registry_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextCore);
};
} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc
new file mode 100644
index 0000000000..e7c230f93a
--- /dev/null
+++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -0,0 +1,168 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_context.h"
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+void SaveResponseCallback(bool* called,
+ int64* store_result,
+ ServiceWorkerRegistrationStatus status,
+ int64 result) {
+ *called = true;
+ *store_result = result;
+}
+
+ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
+ bool* called,
+ int64* store_result) {
+ return base::Bind(&SaveResponseCallback, called, store_result);
+}
+
+void CallCompletedCallback(bool* called, ServiceWorkerRegistrationStatus) {
+ *called = true;
+}
+
+ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback(
+ bool* called) {
+ return base::Bind(&CallCompletedCallback, called);
+}
+
+} // namespace
+
+class ServiceWorkerContextTest : public testing::Test {
+ public:
+ ServiceWorkerContextTest()
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
+
+ virtual void SetUp() OVERRIDE {
+ context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL));
+ }
+
+ virtual void TearDown() OVERRIDE { context_.reset(); }
+
+ protected:
+ TestBrowserThreadBundle browser_thread_bundle_;
+ scoped_ptr<ServiceWorkerContextCore> context_;
+};
+
+void RegistrationCallback(
+ scoped_refptr<ServiceWorkerRegistration>* registration,
+ const scoped_refptr<ServiceWorkerRegistration>& result) {
+ *registration = result;
+}
+
+// Make sure basic registration is working.
+TEST_F(ServiceWorkerContextTest, Register) {
+ int64 registration_id = -1L;
+ bool called = false;
+ context_->RegisterServiceWorker(
+ GURL("http://www.example.com/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ MakeRegisteredCallback(&called, &registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_NE(-1L, registration_id);
+}
+
+// Make sure registrations are cleaned up when they are unregistered.
+TEST_F(ServiceWorkerContextTest, Unregister) {
+ GURL pattern("http://www.example.com/*");
+
+ bool called = false;
+ int64 registration_id = -1L;
+ context_->RegisterServiceWorker(
+ pattern,
+ GURL("http://www.example.com/service_worker.js"),
+ MakeRegisteredCallback(&called, &registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
+ context_->UnregisterServiceWorker(pattern, MakeUnregisteredCallback(&called));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+}
+
+// Make sure that when a new registration replaces an existing
+// registration, that the old one is cleaned up.
+TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
+ GURL pattern("http://www.example.com/*");
+
+ bool called = false;
+ int64 old_registration_id = -1L;
+ context_->RegisterServiceWorker(
+ pattern,
+ GURL("http://www.example.com/service_worker.js"),
+ MakeRegisteredCallback(&called, &old_registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
+ int64 new_registration_id = -1L;
+ context_->RegisterServiceWorker(
+ pattern,
+ GURL("http://www.example.com/service_worker_new.js"),
+ MakeRegisteredCallback(&called, &new_registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_NE(old_registration_id, new_registration_id);
+}
+
+// Make sure that when registering a duplicate pattern+script_url
+// combination, that the same registration is used.
+TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
+ GURL pattern("http://www.example.com/*");
+ GURL script_url("http://www.example.com/service_worker.js");
+
+ bool called = false;
+ int64 old_registration_id = -1L;
+ context_->RegisterServiceWorker(
+ pattern,
+ script_url,
+ MakeRegisteredCallback(&called, &old_registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ called = false;
+ int64 new_registration_id = -1L;
+ context_->RegisterServiceWorker(
+ pattern,
+ script_url,
+ MakeRegisteredCallback(&called, &new_registration_id));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_EQ(old_registration_id, new_registration_id);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 696c5c1867..9f6b139f93 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -5,6 +5,7 @@
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
@@ -37,8 +38,11 @@ ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
}
ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
- if (context_)
+ if (context_) {
context_->RemoveAllProviderHostsForProcess(render_process_id_);
+ context_->embedded_worker_registry()->RemoveChildProcessSender(
+ render_process_id_);
+ }
}
void ServiceWorkerDispatcherHost::Init(
@@ -51,6 +55,8 @@ void ServiceWorkerDispatcherHost::Init(
return;
}
context_ = context_wrapper->context()->AsWeakPtr();
+ context_->embedded_worker_registry()->AddChildProcessSender(
+ render_process_id_, this);
}
void ServiceWorkerDispatcherHost::OnDestruct() const {
@@ -83,7 +89,7 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
int32 thread_id,
int32 request_id,
- const GURL& scope,
+ const GURL& pattern,
const GURL& script_url) {
if (!context_ || !context_->IsEnabled()) {
Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
@@ -97,7 +103,7 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
// TODO(alecflett): This check is insufficient for release. Add a
// ServiceWorker-specific policy query in
// ChildProcessSecurityImpl. See http://crbug.com/311631.
- if (scope.GetOrigin() != script_url.GetOrigin()) {
+ if (pattern.GetOrigin() != script_url.GetOrigin()) {
Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError(
thread_id,
request_id,
@@ -110,9 +116,10 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
thread_id, request_id, NextWorkerId()));
}
-void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(int32 thread_id,
- int32 request_id,
- const GURL& scope) {
+void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
+ int32 thread_id,
+ int32 request_id,
+ const GURL& pattern) {
// TODO(alecflett): This check is insufficient for release. Add a
// ServiceWorker-specific policy query in
// ChildProcessSecurityImpl. See http://crbug.com/311631.
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index bb0abf81f7..563e733d3e 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -38,11 +38,11 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
// IPC Message handlers
void OnRegisterServiceWorker(int32 thread_id,
int32 request_id,
- const GURL& scope,
+ const GURL& pattern,
const GURL& script_url);
void OnUnregisterServiceWorker(int32 thread_id,
int32 request_id,
- const GURL& scope);
+ const GURL& pattern);
void OnProviderCreated(int provider_id);
void OnProviderDestroyed(int provider_id);
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index 2276a5aceb..dd50c9149e 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
new file mode 100644
index 0000000000..51ae40ff6a
--- /dev/null
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -0,0 +1,118 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_register_job.h"
+
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+
+namespace content {
+
+ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
+ const base::WeakPtr<ServiceWorkerStorage>& storage,
+ const RegistrationCompleteCallback& callback)
+ : storage_(storage), callback_(callback), weak_factory_(this) {}
+
+ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {}
+
+void ServiceWorkerRegisterJob::StartRegister(const GURL& pattern,
+ const GURL& script_url) {
+ // Set up a chain of callbacks, in reverse order. Each of these
+ // callbacks may be called asynchronously by the previous callback.
+ ServiceWorkerStorage::RegistrationCallback finish_registration(base::Bind(
+ &ServiceWorkerRegisterJob::RegisterComplete, weak_factory_.GetWeakPtr()));
+
+ ServiceWorkerStorage::UnregistrationCallback register_new(
+ base::Bind(&ServiceWorkerRegisterJob::RegisterPatternAndContinue,
+ weak_factory_.GetWeakPtr(),
+ pattern,
+ script_url,
+ finish_registration));
+
+ ServiceWorkerStorage::RegistrationCallback unregister_old(
+ base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue,
+ weak_factory_.GetWeakPtr(),
+ pattern,
+ script_url,
+ register_new));
+
+ storage_->FindRegistrationForPattern(pattern, unregister_old);
+}
+
+void ServiceWorkerRegisterJob::StartUnregister(const GURL& pattern) {
+ // Set up a chain of callbacks, in reverse order. Each of these
+ // callbacks may be called asynchronously by the previous callback.
+ ServiceWorkerStorage::UnregistrationCallback finish_unregistration(
+ base::Bind(&ServiceWorkerRegisterJob::UnregisterComplete,
+ weak_factory_.GetWeakPtr()));
+
+ ServiceWorkerStorage::RegistrationCallback unregister(
+ base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue,
+ weak_factory_.GetWeakPtr(),
+ pattern,
+ GURL(),
+ finish_unregistration));
+
+ storage_->FindRegistrationForPattern(pattern, unregister);
+}
+
+void ServiceWorkerRegisterJob::RegisterPatternAndContinue(
+ const GURL& pattern,
+ const GURL& script_url,
+ const ServiceWorkerStorage::RegistrationCallback& callback,
+ ServiceWorkerRegistrationStatus previous_status) {
+ if (previous_status != REGISTRATION_OK &&
+ previous_status != REGISTRATION_NOT_FOUND) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback,
+ previous_status,
+ scoped_refptr<ServiceWorkerRegistration>()));
+ }
+
+ // TODO: Eventually RegisterInternal will be replaced by an asynchronous
+ // operation. Pass its resulting status through 'callback'.
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ storage_->RegisterInternal(pattern, script_url);
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback, REGISTRATION_OK, registration));
+}
+
+void ServiceWorkerRegisterJob::UnregisterPatternAndContinue(
+ const GURL& pattern,
+ const GURL& new_script_url,
+ const ServiceWorkerStorage::UnregistrationCallback& callback,
+ ServiceWorkerRegistrationStatus previous_status,
+ const scoped_refptr<ServiceWorkerRegistration>& previous_registration) {
+ DCHECK(previous_status == REGISTRATION_OK ||
+ previous_status == REGISTRATION_NOT_FOUND);
+
+ // The previous registration may not exist, which is ok.
+ if (previous_status == REGISTRATION_OK &&
+ (new_script_url.is_empty() ||
+ previous_registration->script_url() != new_script_url)) {
+ // TODO: Eventually UnregisterInternal will be replaced by an
+ // asynchronous operation. Pass its resulting status though
+ // 'callback'.
+ storage_->UnregisterInternal(pattern);
+ }
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, previous_status));
+}
+
+void ServiceWorkerRegisterJob::UnregisterComplete(
+ ServiceWorkerRegistrationStatus status) {
+ callback_.Run(this, status, NULL);
+}
+
+void ServiceWorkerRegisterJob::RegisterComplete(
+ ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration) {
+ callback_.Run(this, status, registration);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_register_job.h b/content/browser/service_worker/service_worker_register_job.h
new file mode 100644
index 0000000000..f1e35d0709
--- /dev/null
+++ b/content/browser/service_worker/service_worker_register_job.h
@@ -0,0 +1,79 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_
+
+#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_registration_status.h"
+#include "content/browser/service_worker/service_worker_storage.h"
+
+namespace content {
+
+// A ServiceWorkerRegisterJob lives only for the lifetime of a single
+// registration or unregistration.
+class ServiceWorkerRegisterJob {
+ public:
+ typedef base::Callback<void(
+ ServiceWorkerRegisterJob* job,
+ ServiceWorkerRegistrationStatus status,
+ ServiceWorkerRegistration* registration)> RegistrationCompleteCallback;
+
+ // All type of jobs (Register and Unregister) complete through a
+ // single call to this callback on the IO thread.
+ ServiceWorkerRegisterJob(const base::WeakPtr<ServiceWorkerStorage>& storage,
+ const RegistrationCompleteCallback& callback);
+ ~ServiceWorkerRegisterJob();
+
+ // The Registration flow includes most or all of the following,
+ // depending on what is already registered:
+ // - creating a ServiceWorkerRegistration instance if there isn't
+ // already something registered
+ // - creating a ServiceWorkerVersion for the new registration instance.
+ // - starting a worker for the ServiceWorkerVersion
+ // - telling the Version to evaluate the script
+ // - firing the 'install' event at the ServiceWorkerVersion
+ // - firing the 'activate' event at the ServiceWorkerVersion
+ // - Waiting for older ServiceWorkerVersions to deactivate
+ // - designating the new version to be the 'active' version
+ // This method should be called once and only once per job.
+ void StartRegister(const GURL& pattern, const GURL& script_url);
+
+ // The Unregistration process is primarily cleanup, removing
+ // everything that was created during the Registration process,
+ // including the ServiceWorkerRegistration itself.
+ // This method should be called once and only once per job.
+ void StartUnregister(const GURL& pattern);
+
+ private:
+ // These are all steps in the registration and unregistration pipeline.
+ void RegisterPatternAndContinue(
+ const GURL& pattern,
+ const GURL& script_url,
+ const ServiceWorkerStorage::RegistrationCallback& callback,
+ ServiceWorkerRegistrationStatus previous_status);
+
+ void UnregisterPatternAndContinue(
+ const GURL& pattern,
+ const GURL& script_url,
+ const ServiceWorkerStorage::UnregistrationCallback& callback,
+ ServiceWorkerRegistrationStatus previous_status,
+ const scoped_refptr<ServiceWorkerRegistration>& previous_registration);
+
+ // These methods are the last internal callback in the callback
+ // chain, and ultimately call callback_.
+ void UnregisterComplete(ServiceWorkerRegistrationStatus status);
+ void RegisterComplete(
+ ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+
+ const base::WeakPtr<ServiceWorkerStorage> storage_;
+ const RegistrationCompleteCallback callback_;
+ base::WeakPtrFactory<ServiceWorkerRegisterJob> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJob);
+};
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_
diff --git a/content/browser/service_worker/service_worker_registration_status.h b/content/browser/service_worker/service_worker_registration_status.h
new file mode 100644
index 0000000000..82ab553ad1
--- /dev/null
+++ b/content/browser/service_worker/service_worker_registration_status.h
@@ -0,0 +1,21 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_STATUS_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_STATUS_H_
+
+namespace content {
+
+// This enum is used to describe the final state of a ServiceWorkerRegistration.
+enum ServiceWorkerRegistrationStatus {
+ REGISTRATION_OK,
+ REGISTRATION_NOT_FOUND,
+ REGISTRATION_INSTALL_FAILED,
+ REGISTRATION_ACTIVATE_FAILED,
+ REGISTRATION_FAILED,
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_STATUS_H_
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index 1ad7895b7b..3fb6611a2f 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -26,7 +26,8 @@ class ServiceWorkerRegistrationTest : public testing::Test {
};
TEST_F(ServiceWorkerRegistrationTest, Shutdown) {
- int64 registration_id = -1L;
+ const int64 registration_id = -1L;
+ const int64 version_id = -1L;
scoped_refptr<ServiceWorkerRegistration> registration =
new ServiceWorkerRegistration(
GURL("http://www.example.com/*"),
@@ -34,7 +35,7 @@ TEST_F(ServiceWorkerRegistrationTest, Shutdown) {
registration_id);
scoped_refptr<ServiceWorkerVersion> active_version =
- new ServiceWorkerVersion(registration);
+ new ServiceWorkerVersion(registration, NULL, version_id);
registration->set_active_version(active_version);
registration->Shutdown();
@@ -54,12 +55,14 @@ TEST_F(ServiceWorkerRegistrationTest, ActivatePending) {
GURL("http://www.example.com/service_worker.js"),
registration_id);
+ const int64 version_1_id = 1L;
+ const int64 version_2_id = 2L;
scoped_refptr<ServiceWorkerVersion> version_1 =
- new ServiceWorkerVersion(registration);
+ new ServiceWorkerVersion(registration, NULL, version_1_id);
registration->set_active_version(version_1);
scoped_refptr<ServiceWorkerVersion> version_2 =
- new ServiceWorkerVersion(registration);
+ new ServiceWorkerVersion(registration, NULL, version_2_id);
registration->set_pending_version(version_2);
registration->ActivatePendingVersion();
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
new file mode 100644
index 0000000000..dc8c7b1f45
--- /dev/null
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -0,0 +1,190 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_storage.h"
+
+#include <string>
+
+#include "base/strings/string_util.h"
+#include "content/browser/service_worker/service_worker_register_job.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/public/browser/browser_thread.h"
+#include "webkit/browser/quota/quota_manager.h"
+
+namespace {
+// This is temporary until we figure out how registration ids will be
+// calculated.
+int64 NextRegistrationId() {
+ static int64 worker_id = 0;
+ return worker_id++;
+}
+} // namespace
+
+namespace content {
+
+const base::FilePath::CharType kServiceWorkerDirectory[] =
+ FILE_PATH_LITERAL("ServiceWorker");
+
+ServiceWorkerStorage::ServiceWorkerStorage(
+ const base::FilePath& path,
+ quota::QuotaManagerProxy* quota_manager_proxy)
+ : quota_manager_proxy_(quota_manager_proxy), weak_factory_(this) {
+ if (!path.empty())
+ path_ = path.Append(kServiceWorkerDirectory);
+}
+
+ServiceWorkerStorage::~ServiceWorkerStorage() {
+ for (PatternToRegistrationMap::const_iterator iter =
+ registration_by_pattern_.begin();
+ iter != registration_by_pattern_.end();
+ ++iter) {
+ iter->second->Shutdown();
+ }
+ registration_by_pattern_.clear();
+}
+
+void ServiceWorkerStorage::FindRegistrationForPattern(
+ const GURL& pattern,
+ const RegistrationCallback& callback) {
+ PatternToRegistrationMap::const_iterator match =
+ registration_by_pattern_.find(pattern);
+ if (match == registration_by_pattern_.end()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback,
+ REGISTRATION_NOT_FOUND,
+ scoped_refptr<ServiceWorkerRegistration>()));
+ return;
+ }
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback, REGISTRATION_OK, match->second));
+}
+
+void ServiceWorkerStorage::FindRegistrationForDocument(
+ const GURL& document_url,
+ const RegistrationCallback& callback) {
+ // TODO(alecflett): This needs to be synchronous in the fast path,
+ // but asynchronous in the slow path (when the patterns have to be
+ // loaded from disk). For now it is always pessimistically async.
+ for (PatternToRegistrationMap::const_iterator it =
+ registration_by_pattern_.begin();
+ it != registration_by_pattern_.end();
+ ++it) {
+ if (PatternMatches(it->first, document_url)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback,
+ REGISTRATION_OK,
+ scoped_refptr<ServiceWorkerRegistration>(it->second)));
+ return;
+ }
+ }
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback,
+ REGISTRATION_NOT_FOUND,
+ scoped_refptr<ServiceWorkerRegistration>()));
+}
+
+void ServiceWorkerStorage::Register(const GURL& pattern,
+ const GURL& script_url,
+ const RegistrationCallback& callback) {
+ scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
+ weak_factory_.GetWeakPtr(),
+ base::Bind(&ServiceWorkerStorage::RegisterComplete,
+ weak_factory_.GetWeakPtr(),
+ callback)));
+ job->StartRegister(pattern, script_url);
+ registration_jobs_.push_back(job.release());
+}
+
+void ServiceWorkerStorage::Unregister(const GURL& pattern,
+ const UnregistrationCallback& callback) {
+ scoped_ptr<ServiceWorkerRegisterJob> job(new ServiceWorkerRegisterJob(
+ weak_factory_.GetWeakPtr(),
+ base::Bind(&ServiceWorkerStorage::UnregisterComplete,
+ weak_factory_.GetWeakPtr(),
+ callback)));
+ job->StartUnregister(pattern);
+ registration_jobs_.push_back(job.release());
+}
+
+scoped_refptr<ServiceWorkerRegistration> ServiceWorkerStorage::RegisterInternal(
+ const GURL& pattern,
+ const GURL& script_url) {
+
+ PatternToRegistrationMap::const_iterator current(
+ registration_by_pattern_.find(pattern));
+ DCHECK(current == registration_by_pattern_.end() ||
+ current->second->script_url() == script_url);
+
+ if (current == registration_by_pattern_.end()) {
+ scoped_refptr<ServiceWorkerRegistration> registration(
+ new ServiceWorkerRegistration(
+ pattern, script_url, NextRegistrationId()));
+ // TODO(alecflett): version upgrade path.
+ registration_by_pattern_[pattern] = registration;
+ return registration;
+ }
+
+ return current->second;
+}
+
+void ServiceWorkerStorage::UnregisterInternal(const GURL& pattern) {
+ PatternToRegistrationMap::iterator match =
+ registration_by_pattern_.find(pattern);
+ if (match != registration_by_pattern_.end()) {
+ match->second->Shutdown();
+ registration_by_pattern_.erase(match);
+ }
+}
+
+bool ServiceWorkerStorage::PatternMatches(const GURL& pattern,
+ const GURL& url) {
+ // This is a really basic, naive
+ // TODO(alecflett): Formalize what pattern matches mean.
+ // Temporarily borrowed directly from appcache::Namespace::IsMatch().
+ // We have to escape '?' characters since MatchPattern also treats those
+ // as wildcards which we don't want here, we only do '*'s.
+ std::string pattern_spec(pattern.spec());
+ if (pattern.has_query())
+ ReplaceSubstringsAfterOffset(&pattern_spec, 0, "?", "\\?");
+ return MatchPattern(url.spec(), pattern_spec);
+}
+
+void ServiceWorkerStorage::EraseJob(ServiceWorkerRegisterJob* job) {
+ ScopedVector<ServiceWorkerRegisterJob>::iterator job_position =
+ registration_jobs_.begin();
+ for (; job_position != registration_jobs_.end(); ++job_position) {
+ if (*job_position == job) {
+ registration_jobs_.erase(job_position);
+ return;
+ }
+ }
+ NOTREACHED() << "Deleting non-existent job. ";
+}
+
+void ServiceWorkerStorage::UnregisterComplete(
+ const UnregistrationCallback& callback,
+ ServiceWorkerRegisterJob* job,
+ ServiceWorkerRegistrationStatus status,
+ ServiceWorkerRegistration* previous_registration) {
+ callback.Run(status);
+ EraseJob(job);
+}
+
+void ServiceWorkerStorage::RegisterComplete(
+ const RegistrationCallback& callback,
+ ServiceWorkerRegisterJob* job,
+ ServiceWorkerRegistrationStatus status,
+ ServiceWorkerRegistration* registration) {
+ callback.Run(status, registration);
+ EraseJob(job);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
new file mode 100644
index 0000000000..d700ee225b
--- /dev/null
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -0,0 +1,102 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
+
+#include <map>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_vector.h"
+#include "content/browser/service_worker/service_worker_registration_status.h"
+#include "content/common/content_export.h"
+#include "url/gurl.h"
+
+namespace quota {
+class QuotaManagerProxy;
+}
+
+namespace content {
+
+class ServiceWorkerRegistration;
+class ServiceWorkerRegisterJob;
+
+// This class provides an interface to load registration data and
+// instantiate ServiceWorkerRegistration objects. Any asynchronous
+// operations are run through instances of ServiceWorkerRegisterJob.
+class CONTENT_EXPORT ServiceWorkerStorage {
+ public:
+ ServiceWorkerStorage(const base::FilePath& path,
+ quota::QuotaManagerProxy* quota_manager_proxy);
+ ~ServiceWorkerStorage();
+
+ typedef base::Callback<void(ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>&
+ registration)> RegistrationCallback;
+ typedef base::Callback<
+ void(ServiceWorkerRegistrationStatus status)> UnregistrationCallback;
+
+ void FindRegistrationForDocument(const GURL& document_url,
+ const RegistrationCallback& callback);
+ void FindRegistrationForPattern(const GURL& pattern,
+ const RegistrationCallback& callback);
+
+ void Register(const GURL& pattern,
+ const GURL& script_url,
+ const RegistrationCallback& callback);
+
+ void Unregister(const GURL& pattern, const UnregistrationCallback& callback);
+
+ private:
+ friend class ServiceWorkerRegisterJob;
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStorageTest, PatternMatches);
+
+ typedef std::map<GURL, scoped_refptr<ServiceWorkerRegistration> >
+ PatternToRegistrationMap;
+ typedef ScopedVector<ServiceWorkerRegisterJob> RegistrationJobList;
+
+ // TODO(alecflett): These are temporary internal methods providing
+ // synchronous in-memory registration. Eventually these will be
+ // replaced by asynchronous methods that persist registration to disk.
+ scoped_refptr<ServiceWorkerRegistration> RegisterInternal(
+ const GURL& pattern,
+ const GURL& script_url);
+ void UnregisterInternal(const GURL& pattern);
+ static bool PatternMatches(const GURL& pattern, const GURL& script_url);
+
+ // Jobs are removed whenever they are finished or canceled.
+ void EraseJob(ServiceWorkerRegisterJob* job);
+
+ // Called at ServiceWorkerRegisterJob completion.
+ void RegisterComplete(const RegistrationCallback& callback,
+ ServiceWorkerRegisterJob* job,
+ ServiceWorkerRegistrationStatus status,
+ ServiceWorkerRegistration* registration);
+
+ // Called at ServiceWorkerRegisterJob completion.
+ void UnregisterComplete(const UnregistrationCallback& callback,
+ ServiceWorkerRegisterJob* job,
+ ServiceWorkerRegistrationStatus status,
+ ServiceWorkerRegistration* registration);
+
+ // This is the in-memory registration. Eventually the registration will be
+ // persisted to disk.
+ // A list of currently running jobs. This is a temporary structure until we
+ // start managing overlapping registrations explicitly.
+ RegistrationJobList registration_jobs_;
+
+ // in-memory map, to eventually be replaced with persistence
+ PatternToRegistrationMap registration_by_pattern_;
+ scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
+ base::FilePath path_;
+ base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
new file mode 100644
index 0000000000..e82ff3c1d8
--- /dev/null
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -0,0 +1,354 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_storage.h"
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+void SaveRegistrationCallback(
+ ServiceWorkerRegistrationStatus expected_status,
+ bool* called,
+ scoped_refptr<ServiceWorkerRegistration>* registration,
+ ServiceWorkerRegistrationStatus status,
+ const scoped_refptr<ServiceWorkerRegistration>& result) {
+ EXPECT_EQ(expected_status, status);
+ *called = true;
+ *registration = result;
+}
+
+// Creates a callback which both keeps track of if it's been called,
+// as well as the resulting registration. Whent the callback is fired,
+// it ensures that the resulting status matches the expectation.
+// 'called' is useful for making sure a sychronous callback is or
+// isn't called.
+ServiceWorkerStorage::RegistrationCallback SaveRegistration(
+ ServiceWorkerRegistrationStatus expected_status,
+ bool* called,
+ scoped_refptr<ServiceWorkerRegistration>* registration) {
+ *called = false;
+ return base::Bind(
+ &SaveRegistrationCallback, expected_status, called, registration);
+}
+
+void SaveUnregistrationCallback(ServiceWorkerRegistrationStatus expected_status,
+ bool* called,
+ ServiceWorkerRegistrationStatus status) {
+ EXPECT_EQ(expected_status, status);
+ *called = true;
+}
+
+ServiceWorkerStorage::UnregistrationCallback SaveUnregistration(
+ ServiceWorkerRegistrationStatus expected_status,
+ bool* called) {
+ *called = false;
+ return base::Bind(&SaveUnregistrationCallback, expected_status, called);
+}
+
+} // namespace
+
+class ServiceWorkerStorageTest : public testing::Test {
+ public:
+ ServiceWorkerStorageTest()
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
+
+ virtual void SetUp() OVERRIDE {
+ storage_.reset(new ServiceWorkerStorage(base::FilePath(), NULL));
+ }
+
+ virtual void TearDown() OVERRIDE { storage_.reset(); }
+
+ protected:
+ TestBrowserThreadBundle browser_thread_bundle_;
+ scoped_ptr<ServiceWorkerStorage> storage_;
+};
+
+TEST_F(ServiceWorkerStorageTest, PatternMatches) {
+ ASSERT_TRUE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"), GURL("http://www.example.com/")));
+ ASSERT_TRUE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"),
+ GURL("http://www.example.com/page.html")));
+
+ ASSERT_FALSE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"), GURL("https://www.example.com/")));
+ ASSERT_FALSE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"),
+ GURL("https://www.example.com/page.html")));
+
+ ASSERT_FALSE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"), GURL("http://www.foo.com/")));
+ ASSERT_FALSE(ServiceWorkerStorage::PatternMatches(
+ GURL("http://www.example.com/*"), GURL("https://www.foo.com/page.html")));
+}
+
+TEST_F(ServiceWorkerStorageTest, SameDocumentSameRegistration) {
+ scoped_refptr<ServiceWorkerRegistration> original_registration;
+ bool called;
+ storage_->Register(
+ GURL("http://www.example.com/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &original_registration));
+ EXPECT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called);
+
+ scoped_refptr<ServiceWorkerRegistration> registration1;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration1));
+ scoped_refptr<ServiceWorkerRegistration> registration2;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration2));
+
+ ServiceWorkerRegistration* null_registration(NULL);
+ ASSERT_EQ(null_registration, registration1);
+ ASSERT_EQ(null_registration, registration2);
+ EXPECT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called);
+ ASSERT_NE(null_registration, registration1);
+ ASSERT_NE(null_registration, registration2);
+
+ ASSERT_EQ(registration1, registration2);
+}
+
+TEST_F(ServiceWorkerStorageTest, SameMatchSameRegistration) {
+ bool called;
+ scoped_refptr<ServiceWorkerRegistration> original_registration;
+ storage_->Register(
+ GURL("http://www.example.com/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &original_registration));
+ EXPECT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called);
+ ASSERT_NE(static_cast<ServiceWorkerRegistration*>(NULL),
+ original_registration.get());
+
+ scoped_refptr<ServiceWorkerRegistration> registration1;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/one"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration1));
+
+ EXPECT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called);
+
+ scoped_refptr<ServiceWorkerRegistration> registration2;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/two"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration2));
+ EXPECT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called);
+
+ ASSERT_EQ(registration1, registration2);
+}
+
+TEST_F(ServiceWorkerStorageTest, DifferentMatchDifferentRegistration) {
+ bool called1;
+ scoped_refptr<ServiceWorkerRegistration> original_registration1;
+ storage_->Register(
+ GURL("http://www.example.com/one/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called1, &original_registration1));
+
+ bool called2;
+ scoped_refptr<ServiceWorkerRegistration> original_registration2;
+ storage_->Register(
+ GURL("http://www.example.com/two/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called2, &original_registration2));
+
+ EXPECT_FALSE(called1);
+ EXPECT_FALSE(called2);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called2);
+ EXPECT_TRUE(called1);
+
+ scoped_refptr<ServiceWorkerRegistration> registration1;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/one/"),
+ SaveRegistration(REGISTRATION_OK, &called1, &registration1));
+ scoped_refptr<ServiceWorkerRegistration> registration2;
+ storage_->FindRegistrationForDocument(
+ GURL("http://www.example.com/two/"),
+ SaveRegistration(REGISTRATION_OK, &called2, &registration2));
+
+ EXPECT_FALSE(called1);
+ EXPECT_FALSE(called2);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(called2);
+ EXPECT_TRUE(called1);
+
+ ASSERT_NE(registration1, registration2);
+}
+
+// Make sure basic registration is working.
+TEST_F(ServiceWorkerStorageTest, Register) {
+ bool called = false;
+ scoped_refptr<ServiceWorkerRegistration> registration;
+ storage_->Register(GURL("http://www.example.com/*"),
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_NE(scoped_refptr<ServiceWorkerRegistration>(NULL), registration);
+}
+
+// Make sure registrations are cleaned up when they are unregistered.
+TEST_F(ServiceWorkerStorageTest, Unregister) {
+ GURL pattern("http://www.example.com/*");
+
+ bool called;
+ scoped_refptr<ServiceWorkerRegistration> registration;
+ storage_->Register(pattern,
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ storage_->Unregister(pattern, SaveUnregistration(REGISTRATION_OK, &called));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_TRUE(registration->HasOneRef());
+
+ storage_->FindRegistrationForPattern(
+ pattern,
+ SaveRegistration(REGISTRATION_NOT_FOUND, &called, &registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(NULL), registration);
+}
+
+// Make sure that when a new registration replaces an existing
+// registration, that the old one is cleaned up.
+TEST_F(ServiceWorkerStorageTest, RegisterNewScript) {
+ GURL pattern("http://www.example.com/*");
+
+ bool called;
+ scoped_refptr<ServiceWorkerRegistration> old_registration;
+ storage_->Register(
+ pattern,
+ GURL("http://www.example.com/service_worker.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &old_registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern;
+ storage_->FindRegistrationForPattern(
+ pattern,
+ SaveRegistration(REGISTRATION_OK, &called, &old_registration_by_pattern));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_EQ(old_registration, old_registration_by_pattern);
+ old_registration_by_pattern = NULL;
+
+ scoped_refptr<ServiceWorkerRegistration> new_registration;
+ storage_->Register(
+ pattern,
+ GURL("http://www.example.com/service_worker_new.js"),
+ SaveRegistration(REGISTRATION_OK, &called, &new_registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_TRUE(old_registration->HasOneRef());
+
+ ASSERT_NE(old_registration, new_registration);
+
+ scoped_refptr<ServiceWorkerRegistration> new_registration_by_pattern;
+ storage_->FindRegistrationForPattern(
+ pattern, SaveRegistration(REGISTRATION_OK, &called, &new_registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_NE(new_registration_by_pattern, old_registration);
+}
+
+// Make sure that when registering a duplicate pattern+script_url
+// combination, that the same registration is used.
+TEST_F(ServiceWorkerStorageTest, RegisterDuplicateScript) {
+ GURL pattern("http://www.example.com/*");
+ GURL script_url("http://www.example.com/service_worker.js");
+
+ bool called;
+ scoped_refptr<ServiceWorkerRegistration> old_registration;
+ storage_->Register(
+ pattern,
+ script_url,
+ SaveRegistration(REGISTRATION_OK, &called, &old_registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern;
+ storage_->FindRegistrationForPattern(
+ pattern,
+ SaveRegistration(REGISTRATION_OK, &called, &old_registration_by_pattern));
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_TRUE(old_registration_by_pattern);
+
+ scoped_refptr<ServiceWorkerRegistration> new_registration;
+ storage_->Register(
+ pattern,
+ script_url,
+ SaveRegistration(REGISTRATION_OK, &called, &new_registration));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_EQ(old_registration, new_registration);
+
+ ASSERT_FALSE(old_registration->HasOneRef());
+
+ scoped_refptr<ServiceWorkerRegistration> new_registration_by_pattern;
+ storage_->FindRegistrationForPattern(
+ pattern,
+ SaveRegistration(REGISTRATION_OK, &called, &new_registration_by_pattern));
+
+ ASSERT_FALSE(called);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(called);
+
+ ASSERT_EQ(new_registration, old_registration);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index fa3ad3d6bb..a91ac6e9aa 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -4,19 +4,53 @@
#include "content/browser/service_worker/service_worker_version.h"
+#include "base/stl_util.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/embedded_worker_registry.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
namespace content {
ServiceWorkerVersion::ServiceWorkerVersion(
- ServiceWorkerRegistration* registration)
- : is_shutdown_(false), registration_(registration) {}
+ ServiceWorkerRegistration* registration,
+ EmbeddedWorkerRegistry* worker_registry,
+ int64 version_id)
+ : version_id_(version_id),
+ is_shutdown_(false),
+ registration_(registration) {
+ if (worker_registry)
+ embedded_worker_ = worker_registry->CreateWorker();
+}
ServiceWorkerVersion::~ServiceWorkerVersion() { DCHECK(is_shutdown_); }
void ServiceWorkerVersion::Shutdown() {
is_shutdown_ = true;
registration_ = NULL;
+ embedded_worker_.reset();
+}
+
+void ServiceWorkerVersion::StartWorker() {
+ DCHECK(!is_shutdown_);
+ DCHECK(registration_);
+ embedded_worker_->Start(version_id_, registration_->script_url());
+}
+
+void ServiceWorkerVersion::StopWorker() {
+ DCHECK(!is_shutdown_);
+ embedded_worker_->Stop();
+}
+
+void ServiceWorkerVersion::OnAssociateProvider(
+ ServiceWorkerProviderHost* provider_host) {
+ DCHECK(!is_shutdown_);
+ embedded_worker_->AddProcessReference(provider_host->process_id());
+}
+
+void ServiceWorkerVersion::OnUnassociateProvider(
+ ServiceWorkerProviderHost* provider_host) {
+ embedded_worker_->ReleaseProcessReference(provider_host->process_id());
}
} // namespace content
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 93f4459b38..46b75bd686 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -8,12 +8,16 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
class GURL;
namespace content {
+class EmbeddedWorkerInstance;
+class EmbeddedWorkerRegistry;
+class ServiceWorkerProviderHost;
class ServiceWorkerRegistration;
// This class corresponds to a specific version of a ServiceWorker
@@ -51,19 +55,40 @@ class ServiceWorkerRegistration;
class CONTENT_EXPORT ServiceWorkerVersion
: NON_EXPORTED_BASE(public base::RefCounted<ServiceWorkerVersion>) {
public:
- explicit ServiceWorkerVersion(ServiceWorkerRegistration* registration);
+ ServiceWorkerVersion(
+ ServiceWorkerRegistration* registration,
+ EmbeddedWorkerRegistry* worker_registry,
+ int64 version_id);
+
+ int64 version_id() const { return version_id_; }
void Shutdown();
bool is_shutdown() const { return is_shutdown_; }
+ // Starts and stops an embedded worker for this version.
+ void StartWorker();
+ void StopWorker();
+
+ // Called when this version is associated to a provider host.
+ // Non-null |provider_host| must be given.
+ void OnAssociateProvider(ServiceWorkerProviderHost* provider_host);
+ void OnUnassociateProvider(ServiceWorkerProviderHost* provider_host);
+
private:
- ~ServiceWorkerVersion();
friend class base::RefCounted<ServiceWorkerVersion>;
+ ~ServiceWorkerVersion();
+
+ const int64 version_id_;
+
bool is_shutdown_;
scoped_refptr<ServiceWorkerRegistration> registration_;
+ scoped_ptr<EmbeddedWorkerInstance> embedded_worker_;
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion);
};
+
} // namespace content
+
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc
index 7d006b606f..bec8293a6b 100644
--- a/content/browser/session_history_browsertest.cc
+++ b/content/browser/session_history_browsertest.cc
@@ -99,7 +99,7 @@ class SessionHistoryTest : public ContentBrowserTest {
void NavigateAndCheckTitle(const char* filename,
const std::string& expected_title) {
- string16 expected_title16(ASCIIToUTF16(expected_title));
+ base::string16 expected_title16(ASCIIToUTF16(expected_title));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
NavigateToURL(shell(), GetURL(filename));
ASSERT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index 5524091328..ac3c1927c9 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -12,7 +12,6 @@
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
@@ -26,6 +25,7 @@
#include "content/public/test/test_browser_thread.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/url_util.h"
@@ -204,7 +204,8 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
EXPECT_EQ(0, site_delete_counter);
NavigationEntryImpl* e1 = new NavigationEntryImpl(
- instance, 0, url, Referrer(), string16(), PAGE_TRANSITION_LINK, false);
+ instance, 0, url, Referrer(), base::string16(), PAGE_TRANSITION_LINK,
+ false);
// Redundantly setting e1's SiteInstance shouldn't affect the ref count.
e1->set_site_instance(instance);
@@ -212,7 +213,8 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
// Add a second reference
NavigationEntryImpl* e2 = new NavigationEntryImpl(
- instance, 0, url, Referrer(), string16(), PAGE_TRANSITION_LINK, false);
+ instance, 0, url, Referrer(), base::string16(), PAGE_TRANSITION_LINK,
+ false);
// Now delete both entries and be sure the SiteInstance goes away.
delete e1;
@@ -264,7 +266,8 @@ TEST_F(SiteInstanceTest, CloneNavigationEntry) {
&browsing_delete_counter);
NavigationEntryImpl* e1 = new NavigationEntryImpl(
- instance1, 0, url, Referrer(), string16(), PAGE_TRANSITION_LINK, false);
+ instance1, 0, url, Referrer(), base::string16(), PAGE_TRANSITION_LINK,
+ false);
// Clone the entry
NavigationEntryImpl* e2 = new NavigationEntryImpl(*e1);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index f32e1e9382..cca1df07c0 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -36,11 +36,11 @@ class SitePerProcessWebContentsObserver: public WebContentsObserver {
virtual void DidFailProvisionalLoad(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE {
navigation_url_ = validated_url;
navigation_succeeded_ = false;
@@ -48,7 +48,7 @@ class SitePerProcessWebContentsObserver: public WebContentsObserver {
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
- const string16& frame_unique_name,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
diff --git a/content/browser/speech/google_one_shot_remote_engine.cc b/content/browser/speech/google_one_shot_remote_engine.cc
index a421e79c22..575dd5fda6 100644
--- a/content/browser/speech/google_one_shot_remote_engine.cc
+++ b/content/browser/speech/google_one_shot_remote_engine.cc
@@ -121,7 +121,7 @@ bool ParseServerResponse(const std::string& response_body,
const base::DictionaryValue* hypothesis_value =
static_cast<const base::DictionaryValue*>(hypothesis);
- string16 utterance;
+ base::string16 utterance;
if (!hypothesis_value->GetString(kUtteranceString, &utterance)) {
LOG(WARNING) << "ParseServerResponse: Missing utterance value.";
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
index 9edd835b89..4b08958944 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
@@ -91,6 +91,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -100,9 +101,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -179,6 +182,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -188,9 +192,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-mips.mk b/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
index 268927fbcf..8df7587882 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
@@ -91,6 +91,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -100,9 +101,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -179,6 +182,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -188,9 +192,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
index 0e9a25cdc3..f9a8d83119 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
@@ -93,6 +93,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -102,9 +103,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -184,6 +187,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -193,9 +197,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-arm.mk b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
index 9edd835b89..4b08958944 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-arm.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
@@ -91,6 +91,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -100,9 +101,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -179,6 +182,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -188,9 +192,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-mips.mk b/content/browser/speech/proto/speech_proto.target.linux-mips.mk
index 268927fbcf..8df7587882 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-mips.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-mips.mk
@@ -91,6 +91,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -100,9 +101,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -179,6 +182,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -188,9 +192,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-x86.mk b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
index 0e9a25cdc3..f9a8d83119 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-x86.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
@@ -93,6 +93,7 @@ MY_CFLAGS_Debug := \
MY_DEFS_Debug := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -102,9 +103,11 @@ MY_DEFS_Debug := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
@@ -184,6 +187,7 @@ MY_CFLAGS_Release := \
MY_DEFS_Release := \
'-DANGLE_DX11' \
+ '-DV8_DEPRECATION_WARNINGS' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
'-DDISABLE_NACL' \
@@ -193,9 +197,11 @@ MY_DEFS_Release := \
'-DENABLE_CONFIGURATION_POLICY' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index bdc9d1ce21..6ecfa7041a 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -672,7 +672,7 @@ bool SpeechRecognitionManagerImpl::HasAudioInputDevices() {
return audio_manager_->HasAudioInputDevices();
}
-string16 SpeechRecognitionManagerImpl::GetAudioInputDeviceModel() {
+base::string16 SpeechRecognitionManagerImpl::GetAudioInputDeviceModel() {
return audio_manager_->GetAudioInputDeviceModel();
}
diff --git a/content/browser/speech/speech_recognition_manager_impl.h b/content/browser/speech/speech_recognition_manager_impl.h
index 7db7d24d84..d471cf3f29 100644
--- a/content/browser/speech/speech_recognition_manager_impl.h
+++ b/content/browser/speech/speech_recognition_manager_impl.h
@@ -75,7 +75,7 @@ class CONTENT_EXPORT SpeechRecognitionManagerImpl :
int render_view_id,
int request_id) const OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
- virtual string16 GetAudioInputDeviceModel() OVERRIDE;
+ virtual base::string16 GetAudioInputDeviceModel() OVERRIDE;
virtual void ShowAudioInputSettings() OVERRIDE;
// SpeechRecognitionEventListener methods.
diff --git a/content/browser/speech/speech_recognizer_impl_android.cc b/content/browser/speech/speech_recognizer_impl_android.cc
index c771cefba5..2e8c57e87b 100644
--- a/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/content/browser/speech/speech_recognizer_impl_android.cc
@@ -146,7 +146,7 @@ void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env, jobject obj) {
void SpeechRecognizerImplAndroid::OnRecognitionResults(JNIEnv* env, jobject obj,
jobjectArray strings, jfloatArray floats, jboolean provisional) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::vector<string16> options;
+ std::vector<base::string16> options;
AppendJavaStringArrayToStringVector(env, strings, &options);
std::vector<float> scores(options.size(), 0.0);
if (floats != NULL)
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc
index 9dd91d7ae6..b1eb51e320 100644
--- a/content/browser/ssl/ssl_manager.cc
+++ b/content/browser/ssl/ssl_manager.cc
@@ -124,11 +124,14 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
net::CertStatus ssl_cert_status;
int ssl_security_bits;
int ssl_connection_status;
+ SignedCertificateTimestampIDStatusList
+ ssl_signed_certificate_timestamp_ids;
DeserializeSecurityInfo(details.serialized_security_info,
&ssl_cert_id,
&ssl_cert_status,
&ssl_security_bits,
- &ssl_connection_status);
+ &ssl_connection_status,
+ &ssl_signed_certificate_timestamp_ids);
// We may not have an entry if this is a navigation to an initial blank
// page. Reset the SSL information and add the new data we have.
@@ -137,6 +140,8 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
entry->GetSSL().cert_status = ssl_cert_status;
entry->GetSSL().security_bits = ssl_security_bits;
entry->GetSSL().connection_status = ssl_connection_status;
+ entry->GetSSL().signed_certificate_timestamp_ids =
+ ssl_signed_certificate_timestamp_ids;
}
}
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 90f9497223..85934f117b 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -290,8 +290,8 @@ void BlockingGarbageCollect(
base::FileEnumerator enumerator(storage_root, false, kAllFileTypes);
base::FilePath trash_directory;
- if (!file_util::CreateTemporaryDirInDir(storage_root, kTrashDirname,
- &trash_directory)) {
+ if (!base::CreateTemporaryDirInDir(storage_root, kTrashDirname,
+ &trash_directory)) {
// Unable to continue without creating the trash directory so give up.
return;
}
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
index 911f835ab7..ef3b67912a 100644
--- a/content/browser/storage_partition_impl_unittest.cc
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -202,7 +202,7 @@ class RemoveLocalStorageTester {
// stores data in the host file system.
base::FilePath storage_path =
profile_->GetPath().AppendASCII("Local Storage");
- file_util::CreateDirectory(storage_path);
+ base::CreateDirectory(storage_path);
// Write some files.
file_util::WriteFile(storage_path.Append(kDomStorageOrigin1), NULL, 0);
@@ -210,12 +210,16 @@ class RemoveLocalStorageTester {
file_util::WriteFile(storage_path.Append(kDomStorageOrigin3), NULL, 0);
// Tweak their dates.
- file_util::SetLastModifiedTime(storage_path.Append(kDomStorageOrigin1),
- base::Time::Now());
- file_util::SetLastModifiedTime(storage_path.Append(kDomStorageOrigin2),
- base::Time::Now() - base::TimeDelta::FromDays(1));
- file_util::SetLastModifiedTime(storage_path.Append(kDomStorageOrigin3),
- base::Time::Now() - base::TimeDelta::FromDays(60));
+ base::Time now = base::Time::Now();
+ base::TouchFile(storage_path.Append(kDomStorageOrigin1), now, now);
+
+ base::Time one_day_ago = now - base::TimeDelta::FromDays(1);
+ base::TouchFile(storage_path.Append(kDomStorageOrigin2),
+ one_day_ago, one_day_ago);
+
+ base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60);
+ base::TouchFile(storage_path.Append(kDomStorageOrigin3),
+ sixty_days_ago, sixty_days_ago);
}
private:
diff --git a/content/browser/tracing/trace_controller_impl.cc b/content/browser/tracing/trace_controller_impl.cc
deleted file mode 100644
index 8b8433848a..0000000000
--- a/content/browser/tracing/trace_controller_impl.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/tracing/trace_controller_impl.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/debug/trace_event.h"
-#include "base/strings/string_number_conversions.h"
-#include "components/tracing/tracing_messages.h"
-#include "content/browser/tracing/trace_message_filter.h"
-#include "content/browser/tracing/trace_subscriber_stdio.h"
-#include "content/common/child_process_messages.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "content/public/common/content_switches.h"
-
-using base::debug::TraceLog;
-
-namespace content {
-
-namespace {
-
-base::LazyInstance<TraceControllerImpl>::Leaky g_controller =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-TraceController* TraceController::GetInstance() {
- return TraceControllerImpl::GetInstance();
-}
-
-TraceControllerImpl::TraceControllerImpl() :
- subscriber_(NULL),
- pending_end_ack_count_(0),
- pending_bpf_ack_count_(0),
- maximum_bpf_(0.0f),
- is_tracing_(false),
- is_get_category_groups_(false),
- category_filter_(
- base::debug::CategoryFilter::kDefaultCategoryFilterString) {
- TraceLog::GetInstance()->SetNotificationCallback(
- base::Bind(&TraceControllerImpl::OnTraceNotification,
- base::Unretained(this)));
-}
-
-TraceControllerImpl::~TraceControllerImpl() {
- // No need to SetNotificationCallback(nil) on the TraceLog since this is a
- // Leaky instance.
- NOTREACHED();
-}
-
-TraceControllerImpl* TraceControllerImpl::GetInstance() {
- return g_controller.Pointer();
-}
-
-bool TraceControllerImpl::GetKnownCategoryGroupsAsync(
- TraceSubscriber* subscriber) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Known categories come back from child processes with the EndTracingAck
- // message. So to get known categories, just begin and end tracing immediately
- // afterwards. This will ping all the child processes for categories.
- is_get_category_groups_ = true;
- bool success = BeginTracing(subscriber, "*",
- TraceLog::GetInstance()->trace_options()) &&
- EndTracingAsync(subscriber);
- is_get_category_groups_ = success;
- return success;
-}
-
-bool TraceControllerImpl::BeginTracing(TraceSubscriber* subscriber,
- const std::string& category_patterns,
- base::debug::TraceLog::Options options) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!can_begin_tracing(subscriber))
- return false;
-
-#if defined(OS_ANDROID)
- if (!is_get_category_groups_)
- TraceLog::GetInstance()->AddClockSyncMetadataEvent();
-#endif
-
- // Enable tracing
- TraceLog::GetInstance()->SetEnabled(
- base::debug::CategoryFilter(category_patterns), options);
-
- OnTracingBegan(subscriber);
-
- return true;
-}
-
-bool TraceControllerImpl::EndTracingAsync(TraceSubscriber* subscriber) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!can_end_tracing() || subscriber != subscriber_)
- return false;
-
- // Disable local trace early to avoid traces during end-tracing process from
- // interfering with the process.
- TraceLog::GetInstance()->SetDisabled();
-
-#if defined(OS_ANDROID)
- if (!is_get_category_groups_)
- TraceLog::GetInstance()->AddClockSyncMetadataEvent();
-#endif
-
- // There could be a case where there are no child processes and filters_
- // is empty. In that case we can immediately tell the subscriber that tracing
- // has ended. To avoid recursive calls back to the subscriber, we will just
- // use the existing asynchronous OnEndTracingAck code.
- // Count myself (local trace) in pending_end_ack_count_, acked below.
- pending_end_ack_count_ = filters_.size() + 1;
-
- // Handle special case of zero child processes.
- if (pending_end_ack_count_ == 1) {
- // Ack asynchronously now, because we don't have any children to wait for.
- std::vector<std::string> category_groups;
- TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnEndTracingAck,
- base::Unretained(this), category_groups));
- }
-
- // Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendEndTracing();
- }
-
- return true;
-}
-
-bool TraceControllerImpl::GetTraceBufferPercentFullAsync(
- TraceSubscriber* subscriber) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!can_get_buffer_percent_full() || subscriber != subscriber_)
- return false;
-
- maximum_bpf_ = 0.0f;
- pending_bpf_ack_count_ = filters_.size() + 1;
-
- // Handle special case of zero child processes.
- if (pending_bpf_ack_count_ == 1) {
- // Ack asynchronously now, because we don't have any children to wait for.
- float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
- base::Unretained(this), bpf));
- }
-
- // Message all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendGetTraceBufferPercentFull();
- }
-
- return true;
-}
-
-bool TraceControllerImpl::SetWatchEvent(TraceSubscriber* subscriber,
- const std::string& category_name,
- const std::string& event_name) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (subscriber != subscriber_)
- return false;
-
- watch_category_ = category_name;
- watch_name_ = event_name;
-
- TraceLog::GetInstance()->SetWatchEvent(category_name, event_name);
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it)
- it->get()->SendSetWatchEvent(category_name, event_name);
-
- return true;
-}
-
-bool TraceControllerImpl::CancelWatchEvent(TraceSubscriber* subscriber) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (subscriber != subscriber_)
- return false;
-
- watch_category_.clear();
- watch_name_.clear();
-
- TraceLog::GetInstance()->CancelWatchEvent();
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it)
- it->get()->SendCancelWatchEvent();
-
- return true;
-}
-
-void TraceControllerImpl::CancelSubscriber(TraceSubscriber* subscriber) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (subscriber == subscriber_) {
- subscriber_ = NULL;
- // End tracing if necessary.
- if (is_tracing_ && pending_end_ack_count_ == 0)
- EndTracingAsync(NULL);
- }
-}
-
-void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this),
- make_scoped_refptr(filter)));
- return;
- }
-
- filters_.insert(filter);
- if (is_tracing_enabled()) {
- std::string cf_str = category_filter_.ToString();
- filter->SendBeginTracing(cf_str, trace_options_);
- if (!watch_category_.empty())
- filter->SendSetWatchEvent(watch_category_, watch_name_);
- }
-}
-
-void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this),
- make_scoped_refptr(filter)));
- return;
- }
-
- filters_.erase(filter);
-}
-
-void TraceControllerImpl::OnTracingBegan(TraceSubscriber* subscriber) {
- is_tracing_ = true;
-
- subscriber_ = subscriber;
-
- category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter();
- trace_options_ = TraceLog::GetInstance()->trace_options();
-
- // Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendBeginTracing(category_filter_.ToString(), trace_options_);
- }
-}
-
-void TraceControllerImpl::OnEndTracingAck(
- const std::vector<std::string>& known_category_groups) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnEndTracingAck,
- base::Unretained(this), known_category_groups));
- return;
- }
-
- // Merge known_category_groups with known_category_groups_
- known_category_groups_.insert(known_category_groups.begin(),
- known_category_groups.end());
-
- if (pending_end_ack_count_ == 0)
- return;
-
-
- if (--pending_end_ack_count_ == 1) {
- // All acks from subprocesses have been received. Now flush the local trace.
- // During or after this call, our OnLocalTraceDataCollected will be
- // called with the last of the local trace data.
- TraceLog::GetInstance()->Flush(
- base::Bind(&TraceControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)));
- }
-
- if (pending_end_ack_count_ == 0) {
- // All acks (including from the subprocesses and the local trace) have been
- // received.
- is_tracing_ = false;
-
- // Trigger callback if one is set.
- if (subscriber_) {
- if (is_get_category_groups_)
- subscriber_->OnKnownCategoriesCollected(known_category_groups_);
- else
- subscriber_->OnEndTracingComplete();
- // Clear subscriber so that others can use TraceController.
- subscriber_ = NULL;
- }
-
- is_get_category_groups_ = false;
- }
-}
-
-void TraceControllerImpl::OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- // OnTraceDataCollected may be called from any browser thread, either by the
- // local event trace system or from child processes via TraceMessageFilter.
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnTraceDataCollected,
- base::Unretained(this), events_str_ptr));
- return;
- }
-
- // Drop trace events if we are just getting categories.
- if (subscriber_ && !is_get_category_groups_)
- subscriber_->OnTraceDataCollected(events_str_ptr);
-}
-
-void TraceControllerImpl::OnLocalTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr,
- bool has_more_events) {
- if (events_str_ptr->data().size())
- OnTraceDataCollected(events_str_ptr);
-
- if (!has_more_events) {
- // Simulate an EndTrackingAck for the local trace.
- std::vector<std::string> category_groups;
- TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
- OnEndTracingAck(category_groups);
- }
-}
-
-void TraceControllerImpl::OnTraceNotification(int notification) {
- // OnTraceNotification may be called from any browser thread, either by the
- // local event trace system or from child processes via TraceMessageFilter.
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnTraceNotification,
- base::Unretained(this), notification));
- return;
- }
-
- if (notification & base::debug::TraceLog::TRACE_BUFFER_FULL) {
- // EndTracingAsync may return false if tracing is already in the process
- // of being ended. That is ok.
- EndTracingAsync(subscriber_);
- }
- if (notification & base::debug::TraceLog::EVENT_WATCH_NOTIFICATION) {
- if (subscriber_)
- subscriber_->OnEventWatchNotification();
- }
-}
-
-void TraceControllerImpl::OnTraceBufferPercentFullReply(float percent_full) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
- base::Unretained(this), percent_full));
- return;
- }
-
- if (pending_bpf_ack_count_ == 0)
- return;
-
- maximum_bpf_ = (maximum_bpf_ > percent_full)? maximum_bpf_ : percent_full;
-
- if (--pending_bpf_ack_count_ == 0) {
- // Trigger callback if one is set.
- if (subscriber_)
- subscriber_->OnTraceBufferPercentFullReply(maximum_bpf_);
- }
-
- if (pending_bpf_ack_count_ == 1) {
- // The last ack represents local trace, so we need to ack it now. Note that
- // this code only executes if there were child processes.
- float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
- base::Unretained(this), bpf));
- }
-}
-
-} // namespace content
diff --git a/content/browser/tracing/trace_controller_impl.h b/content/browser/tracing/trace_controller_impl.h
deleted file mode 100644
index c058a04df1..0000000000
--- a/content/browser/tracing/trace_controller_impl.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_TRACING_TRACE_CONTROLLER_IMPL_H_
-#define CONTENT_BROWSER_TRACING_TRACE_CONTROLLER_IMPL_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/debug/trace_event.h"
-#include "base/lazy_instance.h"
-#include "content/public/browser/trace_controller.h"
-
-class CommandLine;
-
-namespace content {
-class TraceMessageFilter;
-
-class TraceControllerImpl : public TraceController {
- public:
- static TraceControllerImpl* GetInstance();
-
- // TraceController implementation:
- virtual bool BeginTracing(TraceSubscriber* subscriber,
- const std::string& category_patterns,
- base::debug::TraceLog::Options options) OVERRIDE;
- virtual bool EndTracingAsync(TraceSubscriber* subscriber) OVERRIDE;
- virtual bool GetTraceBufferPercentFullAsync(
- TraceSubscriber* subscriber) OVERRIDE;
- virtual bool SetWatchEvent(TraceSubscriber* subscriber,
- const std::string& category_name,
- const std::string& event_name) OVERRIDE;
- virtual bool CancelWatchEvent(TraceSubscriber* subscriber) OVERRIDE;
- virtual void CancelSubscriber(TraceSubscriber* subscriber) OVERRIDE;
- virtual bool GetKnownCategoryGroupsAsync(TraceSubscriber* subscriber)
- OVERRIDE;
-
- private:
- typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
-
- friend struct base::DefaultLazyInstanceTraits<TraceControllerImpl>;
- friend class TraceMessageFilter;
-
- TraceControllerImpl();
- virtual ~TraceControllerImpl();
-
- bool is_tracing_enabled() const {
- return can_end_tracing();
- }
-
- bool can_end_tracing() const {
- return is_tracing_ && pending_end_ack_count_ == 0;
- }
-
- // Can get Buffer Percent Full
- bool can_get_buffer_percent_full() const {
- return is_tracing_ &&
- pending_end_ack_count_ == 0 &&
- pending_bpf_ack_count_ == 0;
- }
-
- bool can_begin_tracing(TraceSubscriber* subscriber) const {
- return !is_tracing_ &&
- (subscriber_ == NULL || subscriber == subscriber_);
- }
-
- // Methods for use by TraceMessageFilter.
-
- void AddFilter(TraceMessageFilter* filter);
- void RemoveFilter(TraceMessageFilter* filter);
- void OnTracingBegan(TraceSubscriber* subscriber);
- void OnEndTracingAck(const std::vector<std::string>& known_category_groups);
- void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
- void OnTraceNotification(int notification);
- void OnTraceBufferPercentFullReply(float percent_full);
-
- // Callback of TraceLog::Flush() for the local trace.
- void OnLocalTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr,
- bool has_more_events);
-
- FilterMap filters_;
- TraceSubscriber* subscriber_;
- // Pending acks for EndTracingAsync:
- int pending_end_ack_count_;
- // Pending acks for GetTraceBufferPercentFullAsync:
- int pending_bpf_ack_count_;
- float maximum_bpf_;
- bool is_tracing_;
- bool is_get_category_groups_;
- std::set<std::string> known_category_groups_;
- std::string watch_category_;
- std::string watch_name_;
- base::debug::TraceLog::Options trace_options_;
- base::debug::CategoryFilter category_filter_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_TRACING_TRACE_CONTROLLER_IMPL_H_
diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc
index 00fffb9900..35f23dc102 100644
--- a/content/browser/tracing/trace_message_filter.cc
+++ b/content/browser/tracing/trace_message_filter.cc
@@ -5,7 +5,6 @@
#include "content/browser/tracing/trace_message_filter.h"
#include "components/tracing/tracing_messages.h"
-#include "content/browser/tracing/trace_controller_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
namespace content {
@@ -17,6 +16,8 @@ TraceMessageFilter::TraceMessageFilter() :
is_awaiting_buffer_percent_full_ack_(false) {
}
+TraceMessageFilter::~TraceMessageFilter() {}
+
void TraceMessageFilter::OnChannelClosing() {
if (has_child_) {
if (is_awaiting_end_ack_)
@@ -28,8 +29,7 @@ void TraceMessageFilter::OnChannelClosing() {
if (is_awaiting_buffer_percent_full_ack_)
OnTraceBufferPercentFullReply(0.0f);
- TraceControllerImpl::GetInstance()->RemoveFilter(this);
- TracingControllerImpl::GetInstance()->RemoveFilter(this);
+ TracingControllerImpl::GetInstance()->RemoveTraceMessageFilter(this);
}
}
@@ -47,8 +47,8 @@ bool TraceMessageFilter::OnMessageReceived(const IPC::Message& message,
OnTraceDataCollected)
IPC_MESSAGE_HANDLER(TracingHostMsg_MonitoringTraceDataCollected,
OnMonitoringTraceDataCollected)
- IPC_MESSAGE_HANDLER(TracingHostMsg_TraceNotification,
- OnTraceNotification)
+ IPC_MESSAGE_HANDLER(TracingHostMsg_WatchEventMatched,
+ OnWatchEventMatched)
IPC_MESSAGE_HANDLER(TracingHostMsg_TraceBufferPercentFullReply,
OnTraceBufferPercentFullReply)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -109,12 +109,9 @@ void TraceMessageFilter::SendCancelWatchEvent() {
Send(new TracingMsg_CancelWatchEvent);
}
-TraceMessageFilter::~TraceMessageFilter() {}
-
void TraceMessageFilter::OnChildSupportsTracing() {
has_child_ = true;
- TraceControllerImpl::GetInstance()->AddFilter(this);
- TracingControllerImpl::GetInstance()->AddFilter(this);
+ TracingControllerImpl::GetInstance()->AddTraceMessageFilter(this);
}
void TraceMessageFilter::OnEndTracingAck(
@@ -123,7 +120,6 @@ void TraceMessageFilter::OnEndTracingAck(
// child process is compromised.
if (is_awaiting_end_ack_) {
is_awaiting_end_ack_ = false;
- TraceControllerImpl::GetInstance()->OnEndTracingAck(known_categories);
TracingControllerImpl::GetInstance()->OnDisableRecordingAcked(
known_categories);
} else {
@@ -145,7 +141,6 @@ void TraceMessageFilter::OnCaptureMonitoringSnapshotAcked() {
void TraceMessageFilter::OnTraceDataCollected(const std::string& data) {
scoped_refptr<base::RefCountedString> data_ptr(new base::RefCountedString());
data_ptr->data() = data;
- TraceControllerImpl::GetInstance()->OnTraceDataCollected(data_ptr);
TracingControllerImpl::GetInstance()->OnTraceDataCollected(data_ptr);
}
@@ -157,15 +152,13 @@ void TraceMessageFilter::OnMonitoringTraceDataCollected(
data_ptr);
}
-void TraceMessageFilter::OnTraceNotification(int notification) {
- TraceControllerImpl::GetInstance()->OnTraceNotification(notification);
+void TraceMessageFilter::OnWatchEventMatched() {
+ TracingControllerImpl::GetInstance()->OnWatchEventMatched();
}
void TraceMessageFilter::OnTraceBufferPercentFullReply(float percent_full) {
if (is_awaiting_buffer_percent_full_ack_) {
is_awaiting_buffer_percent_full_ack_ = false;
- TraceControllerImpl::GetInstance()->OnTraceBufferPercentFullReply(
- percent_full);
TracingControllerImpl::GetInstance()->OnTraceBufferPercentFullReply(
percent_full);
} else {
diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h
index c8290d952c..0f9e18ed9c 100644
--- a/content/browser/tracing/trace_message_filter.h
+++ b/content/browser/tracing/trace_message_filter.h
@@ -45,7 +45,7 @@ class TraceMessageFilter : public BrowserMessageFilter {
void OnChildSupportsTracing();
void OnEndTracingAck(const std::vector<std::string>& known_categories);
void OnCaptureMonitoringSnapshotAcked();
- void OnTraceNotification(int notification);
+ void OnWatchEventMatched();
void OnTraceBufferPercentFullReply(float percent_full);
void OnTraceDataCollected(const std::string& data);
void OnMonitoringTraceDataCollected(const std::string& data);
diff --git a/content/browser/tracing/trace_subscriber_stdio.cc b/content/browser/tracing/trace_subscriber_stdio.cc
deleted file mode 100644
index da81660939..0000000000
--- a/content/browser/tracing/trace_subscriber_stdio.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/tracing/trace_subscriber_stdio.h"
-
-#include "base/bind.h"
-#include "base/debug/trace_event.h"
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-
-// All method calls on this class are done on a SequencedWorkerPool thread.
-class TraceSubscriberStdio::TraceSubscriberStdioWorker
- : public base::RefCountedThreadSafe<TraceSubscriberStdioWorker> {
- public:
- TraceSubscriberStdioWorker(const base::FilePath& path,
- FileType file_type,
- bool has_system_trace)
- : path_(path),
- file_type_(file_type),
- has_system_trace_(has_system_trace),
- file_(0),
- needs_comma_(false),
- wrote_trace_(false),
- has_pending_system_trace_(false),
- wrote_system_trace_(false) {}
-
- void OnTraceStart() {
- DCHECK(!file_);
- file_ = file_util::OpenFile(path_, "w+");
- if (!IsValid()) {
- LOG(ERROR) << "Failed to open performance trace file: " << path_.value();
- return;
- }
-
- VLOG(0) << "Logging performance trace to file: " << path_.value();
- if (file_type_ == FILE_TYPE_PROPERTY_LIST)
- WriteString("{\"traceEvents\":");
- WriteString("[");
- }
-
- void OnTraceData(const scoped_refptr<base::RefCountedString>& data_ptr) {
- if (!IsValid())
- return;
- DCHECK(!data_ptr->data().empty());
- if (needs_comma_)
- WriteString(",");
- WriteString(data_ptr->data());
- needs_comma_ = true;
- }
-
- void OnSystemTraceData(
- const scoped_refptr<base::RefCountedString>& data_ptr) {
- if (wrote_trace_) {
- WriteSystemTrace(data_ptr);
- End();
- } else {
- pending_system_trace_ = data_ptr;
- has_pending_system_trace_ = true;
- }
- }
-
- void OnTraceEnd() {
- if (!IsValid())
- return;
- WriteString("]");
-
- wrote_trace_ = true;
-
- if (!has_system_trace_ || wrote_system_trace_) {
- End();
- return;
- }
-
- WriteString(",");
- if (has_pending_system_trace_) {
- WriteSystemTrace(pending_system_trace_);
- End();
- }
- }
-
- private:
- friend class base::RefCountedThreadSafe<TraceSubscriberStdioWorker>;
-
- ~TraceSubscriberStdioWorker() {
- CloseFile();
- }
-
- bool IsValid() const {
- return file_ && (0 == ferror(file_));
- }
-
- void CloseFile() {
- if (file_) {
- fclose(file_);
- file_ = 0;
-
- }
- }
-
- void End() {
- if (file_type_ == FILE_TYPE_PROPERTY_LIST)
- WriteString("}");
- CloseFile();
- }
-
- void WriteSystemTrace(const scoped_refptr<base::RefCountedString>& data_ptr) {
- // Newlines need to be replaced with the string "\n" to be parsed correctly.
- // Double quotes need to be replaced with the string "\"".
- // System logs are ASCII.
- const std::string& data = data_ptr->data();
- const char* chars = data.c_str();
- WriteString("\"systemTraceEvents\":\"");
- size_t old_index = 0;
- for (size_t new_index = data.find_first_of("\n\"");
- std::string::npos != new_index;
- old_index = new_index + 1,
- new_index = data.find_first_of("\n\"", old_index)) {
- WriteChars(chars + old_index, new_index - old_index);
- if (chars[new_index] == '\n')
- WriteChars("\\n", 2);
- else
- WriteChars("\\\"", 2);
- }
- WriteChars(chars + old_index, data.size() - old_index);
- WriteString("\"");
- wrote_system_trace_ = true;
- }
-
- void WriteChars(const char* output_chars, size_t size) {
- if (size == 0)
- return;
-
- if (IsValid()) {
- size_t written = fwrite(output_chars, 1, size, file_);
- if (written != size) {
- LOG(ERROR) << "Error " << ferror(file_) << " in fwrite() to trace file";
- CloseFile();
- }
- }
- }
-
- void WriteString(const std::string& output_str) {
- WriteChars(output_str.data(), output_str.size());
- }
-
- base::FilePath path_;
- const FileType file_type_;
- const bool has_system_trace_;
- FILE* file_;
- bool needs_comma_;
- bool wrote_trace_;
- bool has_pending_system_trace_;
- bool wrote_system_trace_;
- scoped_refptr<base::RefCountedString> pending_system_trace_;
- DISALLOW_COPY_AND_ASSIGN(TraceSubscriberStdioWorker);
-};
-
-TraceSubscriberStdio::TraceSubscriberStdio(const base::FilePath& path,
- FileType file_type,
- bool has_system_trace)
- : worker_(new TraceSubscriberStdioWorker(path,
- file_type,
- has_system_trace)) {
- if (has_system_trace)
- CHECK_EQ(FILE_TYPE_PROPERTY_LIST, file_type);
- BrowserThread::PostBlockingPoolSequencedTask(
- __FILE__, FROM_HERE,
- base::Bind(&TraceSubscriberStdioWorker::OnTraceStart, worker_));
-}
-
-TraceSubscriberStdio::~TraceSubscriberStdio() {
-}
-
-void TraceSubscriberStdio::OnEndTracingComplete() {
- BrowserThread::PostBlockingPoolSequencedTask(
- __FILE__, FROM_HERE,
- base::Bind(&TraceSubscriberStdioWorker::OnTraceEnd, worker_));
-}
-
-void TraceSubscriberStdio::OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& data_ptr) {
- BrowserThread::PostBlockingPoolSequencedTask(
- __FILE__, FROM_HERE,
- base::Bind(&TraceSubscriberStdioWorker::OnTraceData, worker_, data_ptr));
-}
-
-void TraceSubscriberStdio::OnEndSystemTracing(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- BrowserThread::PostBlockingPoolSequencedTask(
- __FILE__, FROM_HERE,
- base::Bind(&TraceSubscriberStdioWorker::OnSystemTraceData,
- worker_,
- events_str_ptr));
-}
-
-} // namespace content
diff --git a/content/browser/tracing/trace_subscriber_stdio.h b/content/browser/tracing/trace_subscriber_stdio.h
deleted file mode 100644
index b9fc4f74c1..0000000000
--- a/content/browser/tracing/trace_subscriber_stdio.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_TRACING_TRACE_SUBSCRIBER_STDIO_H_
-#define CONTENT_BROWSER_TRACING_TRACE_SUBSCRIBER_STDIO_H_
-
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "content/public/browser/trace_subscriber.h"
-#include "content/common/content_export.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace content {
-
-// Stdio implementation of TraceSubscriber. Use this to write traces to a file.
-class CONTENT_EXPORT TraceSubscriberStdio
- : NON_EXPORTED_BASE(public TraceSubscriber) {
- public:
- enum FileType {
- // Output file as array, representing trace events:
- // [event1, event2, ...]
- FILE_TYPE_ARRAY,
- // Output file as property list with one or two items:
- // {traceEvents: [event1, event2, ...],
- // systemTraceEvents: "event1\nevent2\n..." // optional}
- FILE_TYPE_PROPERTY_LIST
- };
-
- // has_system_trace indicates whether system trace events are expected.
- TraceSubscriberStdio(const base::FilePath& path,
- FileType file_type,
- bool has_system_trace);
- virtual ~TraceSubscriberStdio();
-
- // Implementation of TraceSubscriber
- virtual void OnEndTracingComplete() OVERRIDE;
- virtual void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& data_ptr) OVERRIDE;
-
- // To be used as callback to DebugDaemonClient::RequestStopSystemTracing().
- virtual void OnEndSystemTracing(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
-
- private:
- class TraceSubscriberStdioWorker;
- scoped_refptr<TraceSubscriberStdioWorker> worker_;
- DISALLOW_COPY_AND_ASSIGN(TraceSubscriberStdio);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_TRACING_TRACE_SUBSCRIBER_STDIO_H_
diff --git a/content/browser/tracing/trace_subscriber_stdio_unittest.cc b/content/browser/tracing/trace_subscriber_stdio_unittest.cc
deleted file mode 100644
index 10e51a968d..0000000000
--- a/content/browser/tracing/trace_subscriber_stdio_unittest.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/tracing/trace_subscriber_stdio.h"
-
-#include "base/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "content/public/browser/browser_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class TraceSubscriberStdioTest : public ::testing::Test {};
-
-TEST_F(TraceSubscriberStdioTest, CanWriteArray) {
- base::ScopedTempDir trace_dir;
- ASSERT_TRUE(trace_dir.CreateUniqueTempDir());
- base::FilePath trace_file(trace_dir.path().AppendASCII("trace.txt"));
- {
- TraceSubscriberStdio subscriber(trace_file,
- TraceSubscriberStdio::FILE_TYPE_ARRAY,
- false);
-
- std::string foo("foo");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&foo)));
-
- std::string bar("bar");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&bar)));
-
- subscriber.OnEndTracingComplete();
- }
- BrowserThread::GetBlockingPool()->FlushForTesting();
- std::string result;
- EXPECT_TRUE(base::ReadFileToString(trace_file, &result));
- EXPECT_EQ("[foo,bar]", result);
-}
-
-TEST_F(TraceSubscriberStdioTest, CanWritePropertyList) {
- base::ScopedTempDir trace_dir;
- ASSERT_TRUE(trace_dir.CreateUniqueTempDir());
- base::FilePath trace_file(trace_dir.path().AppendASCII("trace.txt"));
- {
- TraceSubscriberStdio subscriber(
- trace_file,
- TraceSubscriberStdio::FILE_TYPE_PROPERTY_LIST,
- false);
-
- std::string foo("foo");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&foo)));
-
- std::string bar("bar");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&bar)));
-
- subscriber.OnEndTracingComplete();
- }
- BrowserThread::GetBlockingPool()->FlushForTesting();
- std::string result;
- EXPECT_TRUE(base::ReadFileToString(trace_file, &result));
- EXPECT_EQ("{\"traceEvents\":[foo,bar]}", result);
-}
-
-TEST_F(TraceSubscriberStdioTest, CanWriteSystemDataFirst) {
- base::ScopedTempDir trace_dir;
- ASSERT_TRUE(trace_dir.CreateUniqueTempDir());
- base::FilePath trace_file(trace_dir.path().AppendASCII("trace.txt"));
- {
- TraceSubscriberStdio subscriber(
- trace_file,
- TraceSubscriberStdio::FILE_TYPE_PROPERTY_LIST,
- true);
-
- std::string foo("foo");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&foo)));
-
- std::string bar("bar");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&bar)));
-
- std::string systemTrace("event1\nev\"ent\"2\n");
- subscriber.OnEndSystemTracing(
- make_scoped_refptr(base::RefCountedString::TakeString(&systemTrace)));
- subscriber.OnEndTracingComplete();
- }
- BrowserThread::GetBlockingPool()->FlushForTesting();
- std::string result;
- EXPECT_TRUE(base::ReadFileToString(trace_file, &result));
- EXPECT_EQ(
- "{\"traceEvents\":[foo,bar],\""
- "systemTraceEvents\":\"event1\\nev\\\"ent\\\"2\\n\"}",
- result);
-}
-
-TEST_F(TraceSubscriberStdioTest, CanWriteSystemDataLast) {
- base::ScopedTempDir trace_dir;
- ASSERT_TRUE(trace_dir.CreateUniqueTempDir());
- base::FilePath trace_file(trace_dir.path().AppendASCII("trace.txt"));
- {
- TraceSubscriberStdio subscriber(
- trace_file,
- TraceSubscriberStdio::FILE_TYPE_PROPERTY_LIST,
- true);
-
- std::string foo("foo");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&foo)));
-
- std::string bar("bar");
- subscriber.OnTraceDataCollected(
- make_scoped_refptr(base::RefCountedString::TakeString(&bar)));
-
- std::string systemTrace("event1\nev\"ent\"2\n");
- subscriber.OnEndTracingComplete();
- subscriber.OnEndSystemTracing(
- make_scoped_refptr(base::RefCountedString::TakeString(&systemTrace)));
- }
- BrowserThread::GetBlockingPool()->FlushForTesting();
- std::string result;
- EXPECT_TRUE(base::ReadFileToString(trace_file, &result));
- EXPECT_EQ(
- "{\"traceEvents\":[foo,bar],\""
- "systemTraceEvents\":\"event1\\nev\\\"ent\\\"2\\n\"}",
- result);
-}
-
-} // namespace content
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc
index 0affc2726a..bccf90af44 100644
--- a/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -51,7 +51,7 @@ class TracingControllerTest : public ContentBrowserTest {
disable_recording_done_callback_count_++;
EXPECT_TRUE(PathExists(file_path));
int64 file_size;
- file_util::GetFileSize(file_path, &file_size);
+ base::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
last_actual_recording_file_path_ = file_path;
@@ -72,7 +72,7 @@ class TracingControllerTest : public ContentBrowserTest {
capture_monitoring_snapshot_done_callback_count_++;
EXPECT_TRUE(PathExists(file_path));
int64 file_size;
- file_util::GetFileSize(file_path, &file_size);
+ base::GetFileSize(file_path, &file_size);
EXPECT_TRUE(file_size > 0);
quit_callback.Run();
last_actual_monitoring_file_path_ = file_path;
@@ -122,8 +122,7 @@ class TracingControllerTest : public ContentBrowserTest {
base::Unretained(this),
run_loop.QuitClosure());
bool result = controller->EnableRecording(
- base::debug::CategoryFilter(""), TracingController::Options(),
- callback);
+ "", TracingController::DEFAULT_OPTIONS, callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_recording_done_callback_count(), 1);
@@ -155,8 +154,7 @@ class TracingControllerTest : public ContentBrowserTest {
base::Unretained(this),
run_loop.QuitClosure());
bool result = controller->EnableMonitoring(
- base::debug::CategoryFilter(""), TracingController::ENABLE_SAMPLING,
- callback);
+ "", TracingController::ENABLE_SAMPLING, callback);
ASSERT_TRUE(result);
run_loop.Run();
EXPECT_EQ(enable_monitoring_done_callback_count(), 1);
@@ -169,7 +167,8 @@ class TracingControllerTest : public ContentBrowserTest {
CaptureMonitoringSnapshotDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- controller->CaptureMonitoringSnapshot(result_file_path, callback);
+ ASSERT_TRUE(controller->CaptureMonitoringSnapshot(result_file_path,
+ callback));
run_loop.Run();
EXPECT_EQ(capture_monitoring_snapshot_done_callback_count(), 1);
}
@@ -208,7 +207,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest, GetCategories) {
base::Bind(&TracingControllerTest::GetCategoriesDoneCallbackTest,
base::Unretained(this),
run_loop.QuitClosure());
- controller->GetCategories(callback);
+ ASSERT_TRUE(controller->GetCategories(callback));
run_loop.Run();
EXPECT_EQ(get_categories_done_callback_count(), 1);
}
@@ -220,7 +219,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest, EnableAndDisableRecording) {
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
EnableAndDisableRecordingWithFilePath) {
base::FilePath file_path;
- file_util::CreateTemporaryFile(&file_path);
+ base::CreateTemporaryFile(&file_path);
TestEnableAndDisableRecording(file_path);
EXPECT_EQ(file_path.value(), last_actual_recording_file_path().value());
}
@@ -231,7 +230,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest,
TracingController* controller = TracingController::GetInstance();
EXPECT_TRUE(controller->EnableRecording(
- base::debug::CategoryFilter(""), TracingController::Options(),
+ "", TracingController::DEFAULT_OPTIONS,
TracingController::EnableRecordingDoneCallback()));
EXPECT_TRUE(controller->DisableRecording(
base::FilePath(), TracingController::TracingFileResultCallback()));
@@ -246,7 +245,7 @@ IN_PROC_BROWSER_TEST_F(TracingControllerTest,
IN_PROC_BROWSER_TEST_F(TracingControllerTest,
EnableCaptureAndDisableMonitoringWithFilePath) {
base::FilePath file_path;
- file_util::CreateTemporaryFile(&file_path);
+ base::CreateTemporaryFile(&file_path);
TestEnableCaptureAndDisableMonitoring(file_path);
EXPECT_EQ(file_path.value(), last_actual_monitoring_file_path().value());
}
@@ -258,7 +257,7 @@ IN_PROC_BROWSER_TEST_F(
TracingController* controller = TracingController::GetInstance();
EXPECT_TRUE(controller->EnableMonitoring(
- base::debug::CategoryFilter(""), TracingController::ENABLE_SAMPLING,
+ "", TracingController::ENABLE_SAMPLING,
TracingController::EnableMonitoringDoneCallback()));
controller->CaptureMonitoringSnapshot(
base::FilePath(), TracingController::TracingFileResultCallback());
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index 1340b67e99..bc7cee2f93 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/tracing/tracing_controller_impl.h"
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "base/file_util.h"
#include "base/json/string_escape.h"
#include "base/strings/string_number_conversions.h"
@@ -66,8 +67,8 @@ TracingControllerImpl::ResultFile::ResultFile(const base::FilePath& path)
void TracingControllerImpl::ResultFile::OpenTask() {
if (path_.empty())
- file_util::CreateTemporaryFile(&path_);
- file_ = file_util::OpenFile(path_, "w");
+ base::CreateTemporaryFile(&path_);
+ file_ = base::OpenFile(path_, "w");
if (!file_) {
LOG(ERROR) << "Failed to open " << path_.value();
return;
@@ -103,7 +104,7 @@ void TracingControllerImpl::ResultFile::CloseTask(
const char* trailout = "]}";
size_t written = fwrite(trailout, strlen(trailout), 1, file_);
DCHECK(written == 1);
- file_util::CloseFile(file_);
+ base::CloseFile(file_);
file_ = NULL;
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
@@ -118,9 +119,7 @@ TracingControllerImpl::TracingControllerImpl() :
// Tracing may have been enabled by ContentMainRunner if kTraceStartup
// is specified in command line.
is_recording_(TraceLog::GetInstance()->IsEnabled()),
- is_monitoring_(false),
- category_filter_(
- base::debug::CategoryFilter::kDefaultCategoryFilterString) {
+ is_monitoring_(false) {
}
TracingControllerImpl::~TracingControllerImpl() {
@@ -132,7 +131,7 @@ TracingControllerImpl* TracingControllerImpl::GetInstance() {
return g_controller.Pointer();
}
-void TracingControllerImpl::GetCategories(
+bool TracingControllerImpl::GetCategories(
const GetCategoriesDoneCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -140,14 +139,19 @@ void TracingControllerImpl::GetCategories(
// message. So to get known categories, just begin and end tracing immediately
// afterwards. This will ping all the child processes for categories.
pending_get_categories_done_callback_ = callback;
- EnableRecording(base::debug::CategoryFilter("*"),
- TracingController::Options(),
- EnableRecordingDoneCallback());
- DisableRecording(base::FilePath(), TracingFileResultCallback());
+ if (!EnableRecording("*", TracingController::Options(),
+ EnableRecordingDoneCallback())) {
+ pending_get_categories_done_callback_.Reset();
+ return false;
+ }
+
+ bool ok = DisableRecording(base::FilePath(), TracingFileResultCallback());
+ DCHECK(ok);
+ return true;
}
bool TracingControllerImpl::EnableRecording(
- const base::debug::CategoryFilter& filter,
+ const std::string& category_filter,
TracingController::Options options,
const EnableRecordingDoneCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -168,13 +172,14 @@ bool TracingControllerImpl::EnableRecording(
}
// TODO(haraken): How to handle ENABLE_SYSTRACE?
- TraceLog::GetInstance()->SetEnabled(filter, trace_options);
+ TraceLog::GetInstance()->SetEnabled(
+ base::debug::CategoryFilter(category_filter), trace_options);
is_recording_ = true;
- category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter();
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendBeginTracing(category_filter_.ToString(), trace_options);
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
+ it->get()->SendBeginTracing(category_filter, trace_options);
}
if (!callback.is_null())
@@ -204,15 +209,13 @@ bool TracingControllerImpl::DisableRecording(
if (!callback.is_null() || !result_file_path.empty())
result_file_.reset(new ResultFile(result_file_path));
- // There could be a case where there are no child processes and filters_
- // is empty. In that case we can immediately tell the subscriber that tracing
- // has ended. To avoid recursive calls back to the subscriber, we will just
- // use the existing asynchronous OnDisableRecordingAcked code.
// Count myself (local trace) in pending_disable_recording_ack_count_,
// acked below.
- pending_disable_recording_ack_count_ = filters_.size() + 1;
+ pending_disable_recording_ack_count_ = trace_message_filters_.size() + 1;
- // Handle special case of zero child processes.
+ // Handle special case of zero child processes by immediately telling the
+ // caller that tracing has ended. Use asynchronous OnDisableRecordingAcked
+ // to avoid recursive call back to the caller.
if (pending_disable_recording_ack_count_ == 1) {
// Ack asynchronously now, because we don't have any children to wait for.
std::vector<std::string> category_groups;
@@ -223,14 +226,15 @@ bool TracingControllerImpl::DisableRecording(
}
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
it->get()->SendEndTracing();
}
return true;
}
bool TracingControllerImpl::EnableMonitoring(
- const base::debug::CategoryFilter& filter,
+ const std::string& category_filter,
TracingController::Options options,
const EnableMonitoringDoneCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -248,12 +252,14 @@ bool TracingControllerImpl::EnableMonitoring(
monitoring_tracing_options |= base::debug::TraceLog::MONITOR_SAMPLING;
TraceLog::GetInstance()->SetEnabled(
- filter, base::debug::TraceLog::Options(monitoring_tracing_options));
+ base::debug::CategoryFilter(category_filter),
+ static_cast<TraceLog::Options>(monitoring_tracing_options));
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
- it->get()->SendEnableMonitoring(filter.ToString(),
- base::debug::TraceLog::Options(monitoring_tracing_options));
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
+ it->get()->SendEnableMonitoring(category_filter,
+ static_cast<TraceLog::Options>(monitoring_tracing_options));
}
if (!callback.is_null())
@@ -272,7 +278,8 @@ bool TracingControllerImpl::DisableMonitoring(
TraceLog::GetInstance()->SetDisabled();
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
it->get()->SendDisableMonitoring();
}
@@ -283,34 +290,34 @@ bool TracingControllerImpl::DisableMonitoring(
void TracingControllerImpl::GetMonitoringStatus(
bool* out_enabled,
- base::debug::CategoryFilter* out_filter,
+ std::string* out_category_filter,
TracingController::Options* out_options) {
NOTIMPLEMENTED();
}
-void TracingControllerImpl::CaptureMonitoringSnapshot(
+bool TracingControllerImpl::CaptureMonitoringSnapshot(
const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!can_disable_monitoring())
- return;
+ return false;
if (callback.is_null() && result_file_path.empty())
- return;
+ return false;
pending_capture_monitoring_snapshot_done_callback_ = callback;
monitoring_snapshot_file_.reset(new ResultFile(result_file_path));
- // There could be a case where there are no child processes and filters_
- // is empty. In that case we can immediately tell the subscriber that tracing
- // has ended. To avoid recursive calls back to the subscriber, we will just
- // use the existing asynchronous OnCaptureMonitoringSnapshotAcked code.
// Count myself in pending_capture_monitoring_snapshot_ack_count_,
// acked below.
- pending_capture_monitoring_snapshot_ack_count_ = filters_.size() + 1;
+ pending_capture_monitoring_snapshot_ack_count_ =
+ trace_message_filters_.size() + 1;
- // Handle special case of zero child processes.
+ // Handle special case of zero child processes by immediately telling the
+ // caller that capturing snapshot has ended. Use asynchronous
+ // OnCaptureMonitoringSnapshotAcked to avoid recursive call back to the
+ // caller.
if (pending_capture_monitoring_snapshot_ack_count_ == 1) {
// Ack asynchronously now, because we don't have any children to wait for.
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -319,13 +326,16 @@ void TracingControllerImpl::CaptureMonitoringSnapshot(
}
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
it->get()->SendCaptureMonitoringSnapshot();
}
#if defined(OS_ANDROID)
TraceLog::GetInstance()->AddClockSyncMetadataEvent();
#endif
+
+ return true;
}
bool TracingControllerImpl::GetTraceBufferPercentFull(
@@ -338,7 +348,8 @@ bool TracingControllerImpl::GetTraceBufferPercentFull(
pending_trace_buffer_percent_full_callback_ = callback;
// Count myself in pending_trace_buffer_percent_full_ack_count_, acked below.
- pending_trace_buffer_percent_full_ack_count_ = filters_.size() + 1;
+ pending_trace_buffer_percent_full_ack_count_ =
+ trace_message_filters_.size() + 1;
maximum_trace_buffer_percent_full_ = 0;
// Handle special case of zero child processes.
@@ -350,36 +361,86 @@ bool TracingControllerImpl::GetTraceBufferPercentFull(
}
// Notify all child processes.
- for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
it->get()->SendGetTraceBufferPercentFull();
}
return true;
}
-void TracingControllerImpl::AddFilter(TraceMessageFilter* filter) {
+bool TracingControllerImpl::SetWatchEvent(
+ const std::string& category_name,
+ const std::string& event_name,
+ const WatchEventCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (callback.is_null())
+ return false;
+
+ watch_category_name_ = category_name;
+ watch_event_name_ = event_name;
+ watch_event_callback_ = callback;
+
+ TraceLog::GetInstance()->SetWatchEvent(
+ category_name, event_name,
+ base::Bind(&TracingControllerImpl::OnWatchEventMatched,
+ base::Unretained(this)));
+
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
+ it->get()->SendSetWatchEvent(category_name, event_name);
+ }
+ return true;
+}
+
+bool TracingControllerImpl::CancelWatchEvent() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!can_cancel_watch_event())
+ return false;
+
+ for (TraceMessageFilterMap::iterator it = trace_message_filters_.begin();
+ it != trace_message_filters_.end(); ++it) {
+ it->get()->SendCancelWatchEvent();
+ }
+
+ watch_event_callback_.Reset();
+ return true;
+}
+
+void TracingControllerImpl::AddTraceMessageFilter(
+ TraceMessageFilter* trace_message_filter) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::AddFilter, base::Unretained(this),
- make_scoped_refptr(filter)));
+ base::Bind(&TracingControllerImpl::AddTraceMessageFilter,
+ base::Unretained(this),
+ make_scoped_refptr(trace_message_filter)));
return;
}
- filters_.insert(filter);
+ trace_message_filters_.insert(trace_message_filter);
+ if (can_cancel_watch_event()) {
+ trace_message_filter->SendSetWatchEvent(watch_category_name_,
+ watch_event_name_);
+ }
if (can_disable_recording()) {
- std::string cf_str = category_filter_.ToString();
- filter->SendBeginTracing(cf_str, TraceLog::GetInstance()->trace_options());
+ trace_message_filter->SendBeginTracing(
+ TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString(),
+ TraceLog::GetInstance()->trace_options());
}
}
-void TracingControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
+void TracingControllerImpl::RemoveTraceMessageFilter(
+ TraceMessageFilter* trace_message_filter) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::RemoveFilter, base::Unretained(this),
- make_scoped_refptr(filter)));
+ base::Bind(&TracingControllerImpl::RemoveTraceMessageFilter,
+ base::Unretained(this),
+ make_scoped_refptr(trace_message_filter)));
return;
}
- filters_.erase(filter);
+ trace_message_filters_.erase(trace_message_filter);
}
void TracingControllerImpl::OnDisableRecordingAcked(
@@ -405,6 +466,7 @@ void TracingControllerImpl::OnDisableRecordingAcked(
TraceLog::GetInstance()->Flush(
base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
base::Unretained(this)));
+ return;
}
if (pending_disable_recording_ack_count_ != 0)
@@ -456,6 +518,7 @@ void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
TraceLog::GetInstance()->FlushButLeaveBufferIntact(
base::Bind(&TracingControllerImpl::OnLocalMonitoringTraceDataCollected,
base::Unretained(this)));
+ return;
}
if (pending_capture_monitoring_snapshot_ack_count_ != 0)
@@ -569,4 +632,16 @@ void TracingControllerImpl::OnTraceBufferPercentFullReply(float percent_full) {
}
}
+void TracingControllerImpl::OnWatchEventMatched() {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::OnWatchEventMatched,
+ base::Unretained(this)));
+ return;
+ }
+
+ if (!watch_event_callback_.is_null())
+ watch_event_callback_.Run();
+}
+
} // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h
index 7eab907ce9..ed3c8fd651 100644
--- a/content/browser/tracing/tracing_controller_impl.h
+++ b/content/browser/tracing/tracing_controller_impl.h
@@ -11,9 +11,12 @@
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
-#include "content/public/browser/trace_subscriber.h"
#include "content/public/browser/tracing_controller.h"
+namespace base {
+class RefCountedString;
+}
+
namespace content {
class TraceMessageFilter;
@@ -23,32 +26,36 @@ class TracingControllerImpl : public TracingController {
static TracingControllerImpl* GetInstance();
// TracingController implementation.
- virtual void GetCategories(
+ virtual bool GetCategories(
const GetCategoriesDoneCallback& callback) OVERRIDE;
virtual bool EnableRecording(
- const base::debug::CategoryFilter& filter,
+ const std::string& category_filter,
TracingController::Options options,
const EnableRecordingDoneCallback& callback) OVERRIDE;
virtual bool DisableRecording(
const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) OVERRIDE;
- virtual bool EnableMonitoring(const base::debug::CategoryFilter& filter,
+ virtual bool EnableMonitoring(const std::string& category_filter,
TracingController::Options options,
const EnableMonitoringDoneCallback& callback) OVERRIDE;
virtual bool DisableMonitoring(
const DisableMonitoringDoneCallback& callback) OVERRIDE;
virtual void GetMonitoringStatus(
bool* out_enabled,
- base::debug::CategoryFilter* out_filter,
+ std::string* out_category_filter,
TracingController::Options* out_options) OVERRIDE;
- virtual void CaptureMonitoringSnapshot(
+ virtual bool CaptureMonitoringSnapshot(
const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) OVERRIDE;
virtual bool GetTraceBufferPercentFull(
const GetTraceBufferPercentFullCallback& callback) OVERRIDE;
+ virtual bool SetWatchEvent(const std::string& category_name,
+ const std::string& event_name,
+ const WatchEventCallback& callback) OVERRIDE;
+ virtual bool CancelWatchEvent() OVERRIDE;
private:
- typedef std::set<scoped_refptr<TraceMessageFilter> > FilterMap;
+ typedef std::set<scoped_refptr<TraceMessageFilter> > TraceMessageFilterMap;
class ResultFile;
friend struct base::DefaultLazyInstanceTraits<TracingControllerImpl>;
@@ -77,9 +84,13 @@ class TracingControllerImpl : public TracingController {
return pending_trace_buffer_percent_full_callback_.is_null();
}
+ bool can_cancel_watch_event() const {
+ return !watch_event_callback_.is_null();
+ }
+
// Methods for use by TraceMessageFilter.
- void AddFilter(TraceMessageFilter* filter);
- void RemoveFilter(TraceMessageFilter* filter);
+ void AddTraceMessageFilter(TraceMessageFilter* trace_message_filter);
+ void RemoveTraceMessageFilter(TraceMessageFilter* trace_message_filter);
void OnTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr);
@@ -102,10 +113,11 @@ class TracingControllerImpl : public TracingController {
void OnCaptureMonitoringSnapshotAcked();
void OnMonitoringSnapshotFileClosed();
- void OnTraceNotification(int notification);
void OnTraceBufferPercentFullReply(float percent_full);
- FilterMap filters_;
+ void OnWatchEventMatched();
+
+ TraceMessageFilterMap trace_message_filters_;
// Pending acks for DisableRecording.
int pending_disable_recording_ack_count_;
// Pending acks for CaptureMonitoringSnapshot.
@@ -122,8 +134,11 @@ class TracingControllerImpl : public TracingController {
TracingFileResultCallback pending_capture_monitoring_snapshot_done_callback_;
GetTraceBufferPercentFullCallback pending_trace_buffer_percent_full_callback_;
+ std::string watch_category_name_;
+ std::string watch_event_name_;
+ WatchEventCallback watch_event_callback_;
+
std::set<std::string> known_category_groups_;
- base::debug::CategoryFilter category_filter_;
scoped_ptr<ResultFile> result_file_;
scoped_ptr<ResultFile> monitoring_snapshot_file_;
DISALLOW_COPY_AND_ASSIGN(TracingControllerImpl);
diff --git a/content/browser/tracing/tracing_ui.cc b/content/browser/tracing/tracing_ui.cc
index 6e471c28a8..e59f5667cb 100644
--- a/content/browser/tracing/tracing_ui.cc
+++ b/content/browser/tracing/tracing_ui.cc
@@ -86,11 +86,10 @@ bool OnBeginRecording(const std::string& data64,
if (use_continuous_tracing)
tracing_options |= TracingController::RECORD_CONTINUOUSLY;
- base::debug::CategoryFilter category_filter(category_filter_string);
return TracingController::GetInstance()->EnableRecording(
- category_filter,
+ category_filter_string,
static_cast<TracingController::Options>(tracing_options),
- base::Bind(OnRecordingEnabledAck, callback));
+ base::Bind(&OnRecordingEnabledAck, callback));
}
void OnRecordingEnabledAck(const WebUIDataSource::GotDataCallback& callback) {
diff --git a/content/browser/web_contents/touch_editable_impl_aura.cc b/content/browser/web_contents/touch_editable_impl_aura.cc
index 6f856251d0..ed002c7d9c 100644
--- a/content/browser/web_contents/touch_editable_impl_aura.cc
+++ b/content/browser/web_contents/touch_editable_impl_aura.cc
@@ -307,7 +307,7 @@ bool TouchEditableImplAura::IsCommandIdEnabled(int command_id) const {
case IDS_APP_COPY:
return has_selection;
case IDS_APP_PASTE: {
- string16 result;
+ base::string16 result;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
return editable && !result.empty();
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc
new file mode 100644
index 0000000000..88922b1922
--- /dev/null
+++ b/content/browser/web_contents/web_contents_android.cc
@@ -0,0 +1,58 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/web_contents_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/logging.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "jni/WebContentsImpl_jni.h"
+
+using base::android::AttachCurrentThread;
+
+namespace content {
+
+// static
+WebContents* WebContents::FromJavaWebContents(
+ jobject jweb_contents_android) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!jweb_contents_android)
+ return NULL;
+
+ WebContentsAndroid* web_contents_android =
+ reinterpret_cast<WebContentsAndroid*>(
+ Java_WebContentsImpl_getNativePointer(AttachCurrentThread(),
+ jweb_contents_android));
+ if (!web_contents_android)
+ return NULL;
+ return web_contents_android->web_contents();
+}
+
+// static
+bool WebContentsAndroid::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+WebContentsAndroid::WebContentsAndroid(WebContents* web_contents)
+ : web_contents_(web_contents),
+ navigation_controller_(&(web_contents->GetController())) {
+ JNIEnv* env = AttachCurrentThread();
+ obj_.Reset(env,
+ Java_WebContentsImpl_create(
+ env,
+ reinterpret_cast<intptr_t>(this),
+ navigation_controller_.GetJavaObject().obj()).obj());
+}
+
+WebContentsAndroid::~WebContentsAndroid() {
+ Java_WebContentsImpl_destroy(AttachCurrentThread(), obj_.obj());
+}
+
+base::android::ScopedJavaLocalRef<jobject>
+WebContentsAndroid::GetJavaObject() {
+ return base::android::ScopedJavaLocalRef<jobject>(obj_);
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h
new file mode 100644
index 0000000000..a9595e2a4d
--- /dev/null
+++ b/content/browser/web_contents/web_contents_android.h
@@ -0,0 +1,46 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_ANDROID_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/supports_user_data.h"
+#include "content/browser/frame_host/navigation_controller_android.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class WebContents;
+
+// Android wrapper around WebContents that provides safer passage from java and
+// back to native and provides java with a means of communicating with its
+// native counterpart.
+class CONTENT_EXPORT WebContentsAndroid
+ : public base::SupportsUserData::Data {
+ public:
+ static bool Register(JNIEnv* env);
+
+ explicit WebContentsAndroid(WebContents* web_contents);
+ virtual ~WebContentsAndroid();
+
+ WebContents* web_contents() const { return web_contents_; }
+
+ base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
+ private:
+ WebContents* web_contents_;
+ NavigationControllerAndroid navigation_controller_;
+ base::android::ScopedJavaGlobalRef<jobject> obj_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebContentsAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_ANDROID_H_
diff --git a/content/browser/web_contents/web_contents_delegate_unittest.cc b/content/browser/web_contents/web_contents_delegate_unittest.cc
index d5d60c3725..0de5919edd 100644
--- a/content/browser/web_contents/web_contents_delegate_unittest.cc
+++ b/content/browser/web_contents/web_contents_delegate_unittest.cc
@@ -5,10 +5,10 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/test/test_browser_context.h"
+#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
diff --git a/content/browser/web_contents/web_contents_drag_win.cc b/content/browser/web_contents/web_contents_drag_win.cc
index 72c17583ed..ffc8713f86 100644
--- a/content/browser/web_contents/web_contents_drag_win.cc
+++ b/content/browser/web_contents/web_contents_drag_win.cc
@@ -227,7 +227,7 @@ void WebContentsDragWin::PrepareDragForDownload(
const GURL& page_url,
const std::string& page_encoding) {
// Parse the download metadata.
- string16 mime_type;
+ base::string16 mime_type;
base::FilePath file_name;
GURL download_url;
if (!ParseDownloadMetadata(drop_data.download_metadata,
@@ -247,8 +247,8 @@ void WebContentsDragWin::PrepareDragForDownload(
UTF16ToUTF8(mime_type),
default_name);
base::FilePath temp_dir_path;
- if (!file_util::CreateNewTempDirectory(
- FILE_PATH_LITERAL("chrome_drag"), &temp_dir_path))
+ if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
+ &temp_dir_path))
return;
base::FilePath download_path =
temp_dir_path.Append(generated_download_file_name);
@@ -284,7 +284,7 @@ void WebContentsDragWin::PrepareDragForFileContents(
// Images without ALT text will only have a file extension so we need to
// synthesize one from the provided extension and URL.
if (file_name.BaseName().RemoveExtension().empty()) {
- const string16 extension = file_name.Extension();
+ const base::string16 extension = file_name.Extension();
// Retrieve the name from the URL.
file_name = base::FilePath(
net::GetSuggestedFilename(drop_data.url, "", "", "", "", ""));
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b83285caf6..d9ac631726 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
+#include "base/process/process.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -29,7 +30,8 @@
#include "content/browser/download/save_package.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
-#include "content/browser/frame_host/navigator.h"
+#include "content/browser/frame_host/navigator_impl.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/message_port_message_filter.h"
@@ -45,6 +47,7 @@
#include "content/browser/webui/web_ui_impl.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
+#include "content/common/frame_messages.h"
#include "content/common/image_messages.h"
#include "content/common/ssl_status_serialization.h"
#include "content/common/view_messages.h"
@@ -73,6 +76,7 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
+#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
@@ -89,6 +93,7 @@
#if defined(OS_ANDROID)
#include "content/browser/android/date_time_chooser_android.h"
#include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
+#include "content/browser/web_contents/web_contents_android.h"
#include "content/common/java_bridge_messages.h"
#include "content/public/browser/android/content_view_core.h"
#endif
@@ -154,6 +159,10 @@ namespace {
const char kDotGoogleDotCom[] = ".google.com";
+#if defined(OS_ANDROID)
+const char kWebContentsAndroidKey[] = "web_contents_android";
+#endif // OS_ANDROID
+
base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
@@ -343,12 +352,13 @@ WebContentsImpl::WebContentsImpl(
#if defined(OS_WIN) && defined(USE_AURA)
accessible_parent_(NULL),
#endif
- frame_tree_(new Navigator(&controller_, this), this, this, this),
+ frame_tree_(new NavigatorImpl(&controller_, this),
+ this, this, this, this),
is_loading_(false),
crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
crashed_error_code_(0),
waiting_for_response_(false),
- load_state_(net::LOAD_STATE_IDLE, string16()),
+ load_state_(net::LOAD_STATE_IDLE, base::string16()),
upload_size_(0),
upload_position_(0),
displayed_insecure_content_(false),
@@ -363,7 +373,7 @@ WebContentsImpl::WebContentsImpl(
maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
temporary_zoom_settings_(false),
color_chooser_identifier_(0),
- message_source_(NULL),
+ render_view_message_source_(NULL),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE) {
for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
g_created_callbacks.Get().at(i).Run(this);
@@ -471,6 +481,13 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
const IPC::Message& message) {
+ return OnMessageReceived(render_view_host, NULL, message);
+}
+
+bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
+ RenderFrameHost* render_frame_host,
+ const IPC::Message& message) {
+ DCHECK(render_view_host || render_frame_host);
if (GetWebUI() &&
static_cast<WebUIImpl*>(GetWebUI())->OnMessageReceived(message)) {
return true;
@@ -483,11 +500,13 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
return true;
// Message handlers should be aware of which RenderViewHost sent the
- // message, which is temporarily stored in message_source_.
- message_source_ = render_view_host;
+ // message, which is temporarily stored in render_view_message_source_.
+ render_view_message_source_ = render_view_host;
bool handled = true;
bool message_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
OnDidLoadResourceFromMemoryCache)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
@@ -506,13 +525,11 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
OnRegisterProtocolHandler)
IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply)
- IPC_MESSAGE_HANDLER(ViewHostMsg_CrashedPlugin, OnCrashedPlugin)
IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenColorChooser, OnOpenColorChooser)
IPC_MESSAGE_HANDLER(ViewHostMsg_EndColorChooser, OnEndColorChooser)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetSelectedColorInColorChooser,
OnSetSelectedColorInColorChooser)
- IPC_MESSAGE_HANDLER(ViewHostMsg_PepperPluginHung, OnPepperPluginHung)
IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
OnRequestPpapiBrokerPermission)
@@ -535,7 +552,7 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
OnFirstVisuallyNonEmptyPaint)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
- message_source_ = NULL;
+ render_view_message_source_ = NULL;
if (!message_is_ok) {
RecordAction(UserMetricsAction("BadMessageTerminate_RVD"));
@@ -606,6 +623,10 @@ RenderProcessHost* WebContentsImpl::GetRenderProcessHost() const {
return host ? host->GetProcess() : NULL;
}
+RenderFrameHost* WebContentsImpl::GetMainFrame() {
+ return frame_tree_.root()->render_frame_host();
+}
+
RenderViewHost* WebContentsImpl::GetRenderViewHost() const {
return GetRenderManager()->current_host();
}
@@ -727,7 +748,7 @@ gfx::NativeViewAccessible accessible_parent) {
}
#endif
-const string16& WebContentsImpl::GetTitle() const {
+const base::string16& WebContentsImpl::GetTitle() const {
// Transient entries take precedence. They are used for interstitial pages
// that are shown on top of existing pages.
NavigationEntry* entry = controller_.GetTransientEntry();
@@ -744,7 +765,7 @@ const string16& WebContentsImpl::GetTitle() const {
entry = controller_.GetVisibleEntry();
if (!(entry && entry->IsViewSourceMode())) {
// Give the Web UI the chance to override our title.
- const string16& title = our_web_ui->GetOverriddenTitle();
+ const base::string16& title = our_web_ui->GetOverriddenTitle();
if (!title.empty())
return title;
}
@@ -832,7 +853,7 @@ const net::LoadStateWithParam& WebContentsImpl::GetLoadState() const {
return load_state_;
}
-const string16& WebContentsImpl::GetLoadStateHost() const {
+const base::string16& WebContentsImpl::GetLoadStateHost() const {
return load_state_host_;
}
@@ -1252,6 +1273,7 @@ void WebContentsImpl::LostMouseLock() {
}
void WebContentsImpl::CreateNewWindow(
+ int render_process_id,
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
@@ -1262,11 +1284,30 @@ void WebContentsImpl::CreateNewWindow(
// SiteInstance in its own BrowsingInstance.
bool is_guest = GetRenderProcessHost()->IsGuest();
+ // If the opener is to be suppressed, the new window can be in any process.
+ // Since routing ids are process specific, we must not have one passed in
+ // as argument here.
+ DCHECK(!params.opener_suppressed || route_id == MSG_ROUTING_NONE);
+
scoped_refptr<SiteInstance> site_instance =
params.opener_suppressed && !is_guest ?
SiteInstance::CreateForURL(GetBrowserContext(), params.target_url) :
GetSiteInstance();
+ // A message to create a new window can only come from the active process for
+ // this WebContentsImpl instance. If any other process sends the request,
+ // it is invalid and the process must be terminated.
+ if (GetRenderProcessHost()->GetID() != render_process_id) {
+ base::ProcessHandle process_handle =
+ RenderProcessHost::FromID(render_process_id)->GetHandle();
+ if (process_handle != base::kNullProcessHandle) {
+ RecordAction(
+ UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
+ base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+ }
+ return;
+ }
+
// We must assign the SessionStorageNamespace before calling Init().
//
// http://crbug.com/142685
@@ -1371,19 +1412,36 @@ void WebContentsImpl::CreateNewWindow(
}
}
-void WebContentsImpl::CreateNewWidget(int route_id,
+void WebContentsImpl::CreateNewWidget(int render_process_id,
+ int route_id,
blink::WebPopupType popup_type) {
- CreateNewWidget(route_id, false, popup_type);
+ CreateNewWidget(render_process_id, route_id, false, popup_type);
}
-void WebContentsImpl::CreateNewFullscreenWidget(int route_id) {
- CreateNewWidget(route_id, true, blink::WebPopupTypeNone);
+void WebContentsImpl::CreateNewFullscreenWidget(int render_process_id,
+ int route_id) {
+ CreateNewWidget(render_process_id, route_id, true, blink::WebPopupTypeNone);
}
-void WebContentsImpl::CreateNewWidget(int route_id,
+void WebContentsImpl::CreateNewWidget(int render_process_id,
+ int route_id,
bool is_fullscreen,
blink::WebPopupType popup_type) {
RenderProcessHost* process = GetRenderProcessHost();
+ // A message to create a new widget can only come from the active process for
+ // this WebContentsImpl instance. If any other process sends the request,
+ // it is invalid and the process must be terminated.
+ if (process->GetID() != render_process_id) {
+ base::ProcessHandle process_handle =
+ RenderProcessHost::FromID(render_process_id)->GetHandle();
+ if (process_handle != base::kNullProcessHandle) {
+ RecordAction(
+ UserMetricsAction("Terminate_ProcessMismatch_CreateNewWidget"));
+ base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+ }
+ return;
+ }
+
RenderWidgetHostImpl* widget_host =
new RenderWidgetHostImpl(this, process, route_id, IsHidden());
created_widgets_.insert(widget_host);
@@ -1978,68 +2036,37 @@ void WebContentsImpl::SetFocusToLocationBar(bool select_all) {
delegate_->SetFocusToLocationBar(select_all);
}
-void WebContentsImpl::DidStartProvisionalLoadForFrame(
- RenderViewHost* render_view_host,
+void WebContentsImpl::DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
int64 frame_id,
int64 parent_frame_id,
bool is_main_frame,
- const GURL& url) {
- bool is_error_page = (url.spec() == kUnreachableWebDataURL);
- bool is_iframe_srcdoc = (url.spec() == kAboutSrcDocURL);
- GURL validated_url(url);
- RenderProcessHost* render_process_host =
- render_view_host->GetProcess();
- RenderViewHost::FilterURL(render_process_host, false, &validated_url);
-
- if (is_main_frame) {
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc) {
+ if (is_main_frame)
DidChangeLoadProgress(0);
- // If there is no browser-initiated pending entry for this navigation and it
- // is not for the error URL, create a pending entry using the current
- // SiteInstance, and ensure the address bar updates accordingly. We don't
- // know the referrer or extra headers at this point, but the referrer will
- // be set properly upon commit.
- NavigationEntryImpl* pending_entry =
- NavigationEntryImpl::FromNavigationEntry(controller_.GetPendingEntry());
- bool has_browser_initiated_pending_entry = pending_entry &&
- !pending_entry->is_renderer_initiated();
- if (!has_browser_initiated_pending_entry && !is_error_page) {
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- controller_.CreateNavigationEntry(validated_url,
- content::Referrer(),
- content::PAGE_TRANSITION_LINK,
- true /* is_renderer_initiated */,
- std::string(),
- GetBrowserContext()));
- entry->set_site_instance(
- static_cast<SiteInstanceImpl*>(GetSiteInstance()));
- // TODO(creis): If there's a pending entry already, find a safe way to
- // update it instead of replacing it and copying over things like this.
- if (pending_entry) {
- entry->set_transferred_global_request_id(
- pending_entry->transferred_global_request_id());
- entry->set_should_replace_entry(pending_entry->should_replace_entry());
- entry->set_redirect_chain(pending_entry->redirect_chain());
- }
- controller_.SetPendingEntry(entry);
- NotifyNavigationStateChanged(content::INVALIDATE_TYPE_URL);
- }
- }
-
// Notify observers about the start of the provisional load.
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidStartProvisionalLoadForFrame(frame_id, parent_frame_id,
is_main_frame, validated_url, is_error_page,
- is_iframe_srcdoc, render_view_host));
+ is_iframe_srcdoc, render_frame_host->render_view_host()));
if (is_main_frame) {
- // Notify observers about the provisional change in the main frame URL.
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- ProvisionalChangeToMainFrameUrl(validated_url,
- render_view_host));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver,
+ observers_,
+ ProvisionalChangeToMainFrameUrl(validated_url,
+ render_frame_host->render_view_host()));
}
}
+void WebContentsImpl::NotifyChangedNavigationState(
+ InvalidateTypes changed_flags) {
+ NotifyNavigationStateChanged(changed_flags);
+}
+
void WebContentsImpl::DidRedirectProvisionalLoad(
RenderViewHost* render_view_host,
int32 page_id,
@@ -2149,8 +2176,11 @@ void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
net::CertStatus cert_status = 0;
int security_bits = -1;
int connection_status = 0;
+ SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids;
DeserializeSecurityInfo(security_info, &cert_id, &cert_status,
- &security_bits, &connection_status);
+ &security_bits, &connection_status,
+ &signed_certificate_timestamp_ids);
+ // TODO(alcutter,eranm): Pass signed_certificate_timestamp_ids into details
LoadFromMemoryCacheDetails details(
url, GetRenderProcessHost()->GetID(), cert_id, cert_status, http_method,
mime_type, resource_type);
@@ -2195,8 +2225,9 @@ void WebContentsImpl::OnDidRunInsecureContent(
}
void WebContentsImpl::OnDocumentLoadedInFrame(int64 frame_id) {
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DocumentLoadedInFrame(frame_id, message_source_));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver, observers_,
+ DocumentLoadedInFrame(frame_id, render_view_message_source_));
}
void WebContentsImpl::OnDidFinishLoad(
@@ -2204,11 +2235,12 @@ void WebContentsImpl::OnDidFinishLoad(
const GURL& url,
bool is_main_frame) {
GURL validated_url(url);
- RenderProcessHost* render_process_host = message_source_->GetProcess();
+ RenderProcessHost* render_process_host =
+ render_view_message_source_->GetProcess();
RenderViewHost::FilterURL(render_process_host, false, &validated_url);
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidFinishLoad(frame_id, validated_url, is_main_frame,
- message_source_));
+ render_view_message_source_));
}
void WebContentsImpl::OnDidFailLoadWithError(
@@ -2216,14 +2248,15 @@ void WebContentsImpl::OnDidFailLoadWithError(
const GURL& url,
bool is_main_frame,
int error_code,
- const string16& error_description) {
+ const base::string16& error_description) {
GURL validated_url(url);
- RenderProcessHost* render_process_host = message_source_->GetProcess();
+ RenderProcessHost* render_process_host =
+ render_view_message_source_->GetProcess();
RenderViewHost::FilterURL(render_process_host, false, &validated_url);
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidFailLoad(frame_id, validated_url, is_main_frame,
error_code, error_description,
- message_source_));
+ render_view_message_source_));
}
void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
@@ -2277,7 +2310,7 @@ void WebContentsImpl::OnJSOutOfMemory() {
void WebContentsImpl::OnRegisterProtocolHandler(const std::string& protocol,
const GURL& url,
- const string16& title,
+ const base::string16& title,
bool user_gesture) {
if (!delegate_)
return;
@@ -2315,27 +2348,30 @@ void WebContentsImpl::OnOpenDateTimeDialog(
date_time_chooser_->ShowDialog(ContentViewCore::FromWebContents(this),
GetRenderViewHost(),
value.dialog_type,
- value.year,
- value.month,
- value.day,
- value.hour,
- value.minute,
- value.second,
- value.milli,
- value.week,
+ value.dialog_value,
value.minimum,
value.maximum,
- value.step);
+ value.step,
+ value.suggestions);
}
void WebContentsImpl::OnJavaBridgeGetChannelHandle(IPC::Message* reply_msg) {
java_bridge_dispatcher_host_manager_->OnGetChannelHandle(
- message_source_, reply_msg);
+ render_view_message_source_, reply_msg);
}
#endif
-void WebContentsImpl::OnCrashedPlugin(const base::FilePath& plugin_path,
+void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
+ const base::FilePath& path,
+ bool is_hung) {
+ UMA_HISTOGRAM_COUNTS("Pepper.PluginHung", 1);
+
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+ PluginHungStatusChanged(plugin_child_id, path, is_hung));
+}
+
+void WebContentsImpl::OnPluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
PluginCrashed(plugin_path, plugin_pid));
@@ -2348,9 +2384,12 @@ void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url,
AppCacheAccessed(manifest_url, blocked_by_policy));
}
-void WebContentsImpl::OnOpenColorChooser(int color_chooser_id,
- SkColor color) {
- ColorChooser* new_color_chooser = delegate_->OpenColorChooser(this, color);
+void WebContentsImpl::OnOpenColorChooser(
+ int color_chooser_id,
+ SkColor color,
+ const std::vector<ColorSuggestion>& suggestions) {
+ ColorChooser* new_color_chooser =
+ delegate_->OpenColorChooser(this, color, suggestions);
if (color_chooser_ == new_color_chooser)
return;
color_chooser_.reset(new_color_chooser);
@@ -2370,15 +2409,6 @@ void WebContentsImpl::OnSetSelectedColorInColorChooser(int color_chooser_id,
color_chooser_->SetSelectedColor(color);
}
-void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
- const base::FilePath& path,
- bool is_hung) {
- UMA_HISTOGRAM_COUNTS("Pepper.PluginHung", 1);
-
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- PluginHungStatusChanged(plugin_child_id, path, is_hung));
-}
-
// This exists for render views that don't have a WebUI, but do have WebUI
// bindings enabled.
void WebContentsImpl::OnWebUISend(const GURL& source_url,
@@ -2470,11 +2500,13 @@ void WebContentsImpl::OnMediaNotification(int64 player_cookie,
"Playing audio");
}
- if (blocker)
- power_save_blockers_[message_source_][player_cookie] = blocker.release();
+ if (blocker) {
+ power_save_blockers_[render_view_message_source_][player_cookie] =
+ blocker.release();
+ }
} else {
- delete power_save_blockers_[message_source_][player_cookie];
- power_save_blockers_[message_source_].erase(player_cookie);
+ delete power_save_blockers_[render_view_message_source_][player_cookie];
+ power_save_blockers_[render_view_message_source_].erase(player_cookie);
}
#endif // !defined(OS_CHROMEOS)
}
@@ -2510,7 +2542,8 @@ void WebContentsImpl::SetIsLoading(RenderViewHost* render_view_host,
return;
if (!is_loading) {
- load_state_ = net::LoadStateWithParam(net::LOAD_STATE_IDLE, string16());
+ load_state_ = net::LoadStateWithParam(net::LOAD_STATE_IDLE,
+ base::string16());
load_state_host_.clear();
upload_size_ = 0;
upload_position_ = 0;
@@ -2612,11 +2645,11 @@ void WebContentsImpl::UpdateMaxPageIDIfNecessary(RenderViewHost* rvh) {
}
bool WebContentsImpl::UpdateTitleForEntry(NavigationEntryImpl* entry,
- const string16& title) {
+ const base::string16& title) {
// For file URLs without a title, use the pathname instead. In the case of a
// synthesized title, we don't want the update to count toward the "one set
// per page of the title to history."
- string16 final_title;
+ base::string16 final_title;
bool explicit_set;
if (entry && entry->GetURL().SchemeIsFile() && title.empty()) {
final_title = UTF8ToUTF16(entry->GetURL().ExtractFileName());
@@ -2700,6 +2733,25 @@ void WebContentsImpl::NotifyNavigationEntryCommitted(
WebContentsObserver, observers_, NavigationEntryCommitted(load_details));
}
+bool WebContentsImpl::OnMessageReceived(RenderFrameHost* render_frame_host,
+ const IPC::Message& message) {
+ return OnMessageReceived(NULL, render_frame_host, message);
+}
+
+void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
+ // Note this is only for subframes, the notification for the main frame
+ // happens in RenderViewCreated.
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ RenderFrameCreated(render_frame_host));
+}
+
+void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ RenderFrameDeleted(render_frame_host));
+}
+
RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() {
return render_view_host_delegate_view_;
}
@@ -2760,6 +2812,13 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
FOR_EACH_OBSERVER(
WebContentsObserver, observers_, RenderViewCreated(render_view_host));
+
+ // We tell the observers now instead of when the main RenderFrameHostImpl is
+ // constructed because otherwise it would be too early (i.e. IPCs sent to the
+ // frame would be dropped because it's not created yet).
+ RenderFrameHost* main_frame = GetMainFrame();
+ FOR_EACH_OBSERVER(
+ WebContentsObserver, observers_, RenderFrameCreated(main_frame));
}
void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
@@ -2969,7 +3028,7 @@ void WebContentsImpl::UpdateState(RenderViewHost* rvh,
void WebContentsImpl::UpdateTitle(RenderViewHost* rvh,
int32 page_id,
- const string16& title,
+ const base::string16& title,
base::i18n::TextDirection title_direction) {
// If we have a title, that's a pretty good indication that we've started
// getting useful data.
@@ -3182,13 +3241,6 @@ void WebContentsImpl::RequestTransferURL(
// Navigations in Web UI pages count as browser-initiated navigations.
params.is_renderer_initiated = false;
-
- // TODO(creis): Remove this line. In the short term, it fixes a regression
- // (http://crbug.com/313572) by partially reverting r231370.
- // The underlying problem is that WebDataSource::replacesCurrentHistoryItem
- // should be returning false when the CWS goes to the sign-in page.
- // See http://crbug.com/311721.
- params.should_replace_current_entry = false;
}
new_contents = OpenURL(params);
@@ -3285,8 +3337,8 @@ void WebContentsImpl::RouteMessageEvent(
void WebContentsImpl::RunJavaScriptMessage(
RenderViewHost* rvh,
- const string16& message,
- const string16& default_prompt,
+ const base::string16& message,
+ const base::string16& default_prompt,
const GURL& frame_url,
JavaScriptMessageType javascript_message_type,
IPC::Message* reply_msg,
@@ -3324,7 +3376,7 @@ void WebContentsImpl::RunJavaScriptMessage(
if (suppress_this_message) {
// If we are suppressing messages, just reply as if the user immediately
// pressed "Cancel".
- OnDialogClosed(rvh, reply_msg, false, string16());
+ OnDialogClosed(rvh, reply_msg, false, base::string16());
}
// OnDialogClosed (two lines up) may have caused deletion of this object (see
@@ -3332,7 +3384,7 @@ void WebContentsImpl::RunJavaScriptMessage(
}
void WebContentsImpl::RunBeforeUnloadConfirm(RenderViewHost* rvh,
- const string16& message,
+ const base::string16& message,
bool is_reload,
IPC::Message* reply_msg) {
RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(rvh);
@@ -3346,7 +3398,7 @@ void WebContentsImpl::RunBeforeUnloadConfirm(RenderViewHost* rvh,
!delegate_->GetJavaScriptDialogManager();
if (suppress_this_message) {
// The reply must be sent to the RVH that sent the request.
- rvhi->JavaScriptDialogClosed(reply_msg, true, string16());
+ rvhi->JavaScriptDialogClosed(reply_msg, true, base::string16());
return;
}
@@ -3359,9 +3411,9 @@ void WebContentsImpl::RunBeforeUnloadConfirm(RenderViewHost* rvh,
}
bool WebContentsImpl::AddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
if (!delegate_)
return false;
return delegate_->AddMessageToConsole(this, level, message, line_no,
@@ -3584,7 +3636,7 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
GetMaxPageIDForSiteInstance(render_view_host->GetSiteInstance());
if (!static_cast<RenderViewHostImpl*>(
- render_view_host)->CreateRenderView(string16(),
+ render_view_host)->CreateRenderView(base::string16(),
opener_route_id,
max_page_id)) {
return false;
@@ -3603,6 +3655,19 @@ bool WebContentsImpl::CreateRenderViewForRenderManager(
}
#if defined(OS_ANDROID)
+base::android::ScopedJavaLocalRef<jobject>
+WebContentsImpl::GetJavaWebContents() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ WebContentsAndroid* web_contents_android =
+ static_cast<WebContentsAndroid*>(GetUserData(kWebContentsAndroidKey));
+ if (!web_contents_android) {
+ web_contents_android = new WebContentsAndroid(this);
+ SetUserData(kWebContentsAndroidKey, web_contents_android);
+ }
+ return web_contents_android->GetJavaObject();
+}
+
bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() {
return CreateRenderViewForRenderManager(GetRenderViewHost(),
MSG_ROUTING_NONE);
@@ -3612,7 +3677,7 @@ bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() {
void WebContentsImpl::OnDialogClosed(RenderViewHost* rvh,
IPC::Message* reply_msg,
bool success,
- const string16& user_input) {
+ const base::string16& user_input) {
if (is_showing_before_unload_dialog_ && !success) {
// If a beforeunload dialog is canceled, we need to stop the throbber from
// spinning, since we forced it to start spinning in Navigate.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 1717077f9a..e790f1524b 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -19,6 +19,7 @@
#include "content/browser/frame_host/navigation_controller_delegate.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_manager.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -49,7 +50,6 @@ class DownloadItem;
class InterstitialPageImpl;
class JavaBridgeDispatcherHostManager;
class JavaScriptDialogManager;
-class Navigator;
class PowerSaveBlocker;
class RenderViewHost;
class RenderViewHostDelegateView;
@@ -65,6 +65,7 @@ class WebContentsImpl;
class WebContentsObserver;
class WebContentsViewPort;
class WebContentsViewDelegate;
+struct ColorSuggestion;
struct FaviconURL;
struct LoadNotificationDetails;
@@ -77,6 +78,7 @@ WebContentsViewPort* CreateWebContentsView(
class CONTENT_EXPORT WebContentsImpl
: public NON_EXPORTED_BASE(WebContents),
+ public NON_EXPORTED_BASE(RenderFrameHostDelegate),
public RenderViewHostDelegate,
public RenderWidgetHostDelegate,
public RenderFrameHostManager::Delegate,
@@ -171,6 +173,7 @@ class CONTENT_EXPORT WebContentsImpl
virtual const NavigationControllerImpl& GetController() const OVERRIDE;
virtual BrowserContext* GetBrowserContext() const OVERRIDE;
virtual RenderProcessHost* GetRenderProcessHost() const OVERRIDE;
+ virtual RenderFrameHost* GetMainFrame() OVERRIDE;
virtual RenderViewHost* GetRenderViewHost() const OVERRIDE;
virtual void GetRenderViewHostAtPosition(
int x,
@@ -192,7 +195,7 @@ class CONTENT_EXPORT WebContentsImpl
virtual void SetParentNativeViewAccessible(
gfx::NativeViewAccessible accessible_parent) OVERRIDE;
#endif
- virtual const string16& GetTitle() const OVERRIDE;
+ virtual const base::string16& GetTitle() const OVERRIDE;
virtual int32 GetMaxPageID() OVERRIDE;
virtual int32 GetMaxPageIDForSiteInstance(
SiteInstance* site_instance) OVERRIDE;
@@ -201,7 +204,7 @@ class CONTENT_EXPORT WebContentsImpl
virtual bool IsLoading() const OVERRIDE;
virtual bool IsWaitingForResponse() const OVERRIDE;
virtual const net::LoadStateWithParam& GetLoadState() const OVERRIDE;
- virtual const string16& GetLoadStateHost() const OVERRIDE;
+ virtual const base::string16& GetLoadStateHost() const OVERRIDE;
virtual uint64 GetUploadSize() const OVERRIDE;
virtual uint64 GetUploadPosition() const OVERRIDE;
virtual std::set<GURL> GetSitesInTab() const OVERRIDE;
@@ -265,6 +268,10 @@ class CONTENT_EXPORT WebContentsImpl
bool is_favicon,
uint32_t max_bitmap_size,
const ImageDownloadCallback& callback) OVERRIDE;
+#if defined(OS_ANDROID)
+ virtual base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents()
+ OVERRIDE;
+#endif
// Implementation of PageNavigator.
virtual WebContents* OpenURL(const OpenURLParams& params) OVERRIDE;
@@ -272,8 +279,13 @@ class CONTENT_EXPORT WebContentsImpl
// Implementation of IPC::Sender.
virtual bool Send(IPC::Message* message) OVERRIDE;
- // RenderViewHostDelegate ----------------------------------------------------
+ // RenderFrameHostDelegate ---------------------------------------------------
+ virtual bool OnMessageReceived(RenderFrameHost* render_frame_host,
+ const IPC::Message& message) OVERRIDE;
+ virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE;
+ virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE;
+ // RenderViewHostDelegate ----------------------------------------------------
virtual RenderViewHostDelegateView* GetDelegateView() OVERRIDE;
virtual RenderViewHostDelegate::RendererManagement*
GetRendererManagementDelegate() OVERRIDE;
@@ -290,12 +302,6 @@ class CONTENT_EXPORT WebContentsImpl
base::TerminationStatus status,
int error_code) OVERRIDE;
virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE;
- virtual void DidStartProvisionalLoadForFrame(
- RenderViewHost* render_view_host,
- int64 frame_id,
- int64 parent_frame_id,
- bool main_frame,
- const GURL& url) OVERRIDE;
virtual void DidRedirectProvisionalLoad(
RenderViewHost* render_view_host,
int32 page_id,
@@ -317,7 +323,7 @@ class CONTENT_EXPORT WebContentsImpl
const PageState& page_state) OVERRIDE;
virtual void UpdateTitle(RenderViewHost* render_view_host,
int32 page_id,
- const string16& title,
+ const base::string16& title,
base::i18n::TextDirection title_direction) OVERRIDE;
virtual void UpdateEncoding(RenderViewHost* render_view_host,
const std::string& encoding) OVERRIDE;
@@ -358,20 +364,20 @@ class CONTENT_EXPORT WebContentsImpl
RenderViewHost* rvh,
const ViewMsg_PostMessage_Params& params) OVERRIDE;
virtual void RunJavaScriptMessage(RenderViewHost* rvh,
- const string16& message,
- const string16& default_prompt,
+ const base::string16& message,
+ const base::string16& default_prompt,
const GURL& frame_url,
JavaScriptMessageType type,
IPC::Message* reply_msg,
bool* did_suppress_message) OVERRIDE;
virtual void RunBeforeUnloadConfirm(RenderViewHost* rvh,
- const string16& message,
+ const base::string16& message,
bool is_reload,
IPC::Message* reply_msg) OVERRIDE;
virtual bool AddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) OVERRIDE;
+ const base::string16& source_id) OVERRIDE;
virtual RendererPreferences GetRendererPrefs(
BrowserContext* browser_context) const OVERRIDE;
virtual WebPreferences GetWebkitPrefs() OVERRIDE;
@@ -405,13 +411,16 @@ class CONTENT_EXPORT WebContentsImpl
bool last_unlocked_by_target) OVERRIDE;
virtual void LostMouseLock() OVERRIDE;
virtual void CreateNewWindow(
+ int render_process_id,
int route_id,
int main_frame_route_id,
const ViewHostMsg_CreateWindow_Params& params,
SessionStorageNamespace* session_storage_namespace) OVERRIDE;
- virtual void CreateNewWidget(int route_id,
+ virtual void CreateNewWidget(int render_process_id,
+ int route_id,
blink::WebPopupType popup_type) OVERRIDE;
- virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE;
+ virtual void CreateNewFullscreenWidget(int render_process_id,
+ int route_id) OVERRIDE;
virtual void ShowCreatedWindow(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
@@ -427,6 +436,19 @@ class CONTENT_EXPORT WebContentsImpl
SiteInstance* instance) OVERRIDE;
virtual FrameTree* GetFrameTree() OVERRIDE;
+ // NavigatorDelegate ---------------------------------------------------------
+
+ virtual void DidStartProvisionalLoad(
+ RenderFrameHostImpl* render_frame_host,
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool is_main_frame,
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc) OVERRIDE;
+ virtual void NotifyChangedNavigationState(
+ InvalidateTypes changed_flags) OVERRIDE;
+
// RenderWidgetHostDelegate --------------------------------------------------
virtual void RenderWidgetDeleted(
@@ -593,12 +615,16 @@ class CONTENT_EXPORT WebContentsImpl
void OnDialogClosed(RenderViewHost* rvh,
IPC::Message* reply_msg,
bool success,
- const string16& user_input);
+ const base::string16& user_input);
// Callback function when requesting permission to access the PPAPI broker.
// |result| is true if permission was granted.
void OnPpapiBrokerPermissionResult(int routing_id, bool result);
+ bool OnMessageReceived(RenderViewHost* render_view_host,
+ RenderFrameHost* render_frame_host,
+ const IPC::Message& message);
+
// IPC message handlers.
void OnDidLoadResourceFromMemoryCache(const GURL& url,
const std::string& security_info,
@@ -616,7 +642,7 @@ class CONTENT_EXPORT WebContentsImpl
const GURL& url,
bool is_main_frame,
int error_code,
- const string16& error_description);
+ const base::string16& error_description);
void OnGoToEntryAtOffset(int offset);
void OnUpdateZoomLimits(int minimum_percent,
int maximum_percent,
@@ -626,7 +652,7 @@ class CONTENT_EXPORT WebContentsImpl
void OnRegisterProtocolHandler(const std::string& protocol,
const GURL& url,
- const string16& title,
+ const base::string16& title,
bool user_gesture);
void OnFindReply(int request_id,
int number_of_matches,
@@ -642,15 +668,17 @@ class CONTENT_EXPORT WebContentsImpl
const ViewHostMsg_DateTimeDialogValue_Params& value);
void OnJavaBridgeGetChannelHandle(IPC::Message* reply_msg);
#endif
- void OnCrashedPlugin(const base::FilePath& plugin_path,
+ void OnPepperPluginHung(int plugin_child_id,
+ const base::FilePath& path,
+ bool is_hung);
+ void OnPluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid);
void OnAppCacheAccessed(const GURL& manifest_url, bool blocked_by_policy);
- void OnOpenColorChooser(int color_chooser_id, SkColor color);
+ void OnOpenColorChooser(int color_chooser_id,
+ SkColor color,
+ const std::vector<ColorSuggestion>& suggestions);
void OnEndColorChooser(int color_chooser_id);
void OnSetSelectedColorInColorChooser(int color_chooser_id, SkColor color);
- void OnPepperPluginHung(int plugin_child_id,
- const base::FilePath& path,
- bool is_hung);
void OnWebUISend(const GURL& source_url,
const std::string& name,
const base::ListValue& args);
@@ -711,7 +739,7 @@ class CONTENT_EXPORT WebContentsImpl
// or the dedicated set title message. It returns true if the new title is
// different and was therefore updated.
bool UpdateTitleForEntry(NavigationEntryImpl* entry,
- const string16& title);
+ const base::string16& title);
// Causes the WebContentsImpl to navigate in the right renderer to |entry|,
// which must be already part of the entries in the navigation controller.
@@ -726,7 +754,8 @@ class CONTENT_EXPORT WebContentsImpl
int CreateOpenerRenderViews(SiteInstance* instance);
// Helper for CreateNewWidget/CreateNewFullscreenWidget.
- void CreateNewWidget(int route_id,
+ void CreateNewWidget(int render_process_id,
+ int route_id,
bool is_fullscreen,
blink::WebPopupType popup_type);
@@ -873,7 +902,7 @@ class CONTENT_EXPORT WebContentsImpl
// The current load state and the URL associated with it.
net::LoadStateWithParam load_state_;
- string16 load_state_host_;
+ base::string16 load_state_host_;
// Upload progress, for displaying in the status bar.
// Set to zero when there is no significant upload happening.
uint64 upload_size_;
@@ -882,7 +911,7 @@ class CONTENT_EXPORT WebContentsImpl
// Data for current page -----------------------------------------------------
// When a title cannot be taken from any entry, this title will be used.
- string16 page_title_when_no_navigation_entry_;
+ base::string16 page_title_when_no_navigation_entry_;
// When a navigation occurs, we record its contents MIME type. It can be
// used to check whether we can do something for some special contents.
@@ -971,9 +1000,10 @@ class CONTENT_EXPORT WebContentsImpl
// member variables that are gone.
NotificationRegistrar registrar_;
- // Used during IPC message dispatching so that the handlers can get a pointer
- // to the RVH through which the message was received.
- RenderViewHost* message_source_;
+ // Used during IPC message dispatching from the RenderView so that the
+ // handlers can get a pointer to the RVH through which the message was
+ // received.
+ RenderViewHost* render_view_message_source_;
// All live RenderWidgetHostImpls that are created by this object and may
// outlive it.
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index d5ac7057c1..7926b4c424 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -7,7 +7,6 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/view_messages.h"
@@ -27,6 +26,7 @@
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -183,7 +183,7 @@ class TestInterstitialPage : public InterstitialPageImpl {
virtual RenderViewHost* CreateRenderViewHost() OVERRIDE {
return new TestRenderViewHost(
SiteInstance::Create(web_contents()->GetBrowserContext()),
- this, this, MSG_ROUTING_NONE, MSG_ROUTING_NONE, false);
+ this, this, this, MSG_ROUTING_NONE, MSG_ROUTING_NONE, false);
}
virtual WebContentsView* CreateWebContentsView() OVERRIDE {
@@ -284,7 +284,7 @@ class TestWebContentsObserver : public WebContentsObserver {
const GURL& validated_url,
bool is_main_frame,
int error_code,
- const string16& error_description,
+ const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE {
last_url_ = validated_url;
}
@@ -318,12 +318,12 @@ TEST_F(WebContentsImplTest, DontUseTitleFromPendingEntry) {
const GURL kGURL("chrome://blah");
controller().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
- EXPECT_EQ(string16(), contents()->GetTitle());
+ EXPECT_EQ(base::string16(), contents()->GetTitle());
}
TEST_F(WebContentsImplTest, UseTitleFromPendingEntryIfSet) {
const GURL kGURL("chrome://blah");
- const string16 title = ASCIIToUTF16("My Title");
+ const base::string16 title = ASCIIToUTF16("My Title");
controller().LoadURL(
kGURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
@@ -2152,7 +2152,7 @@ TEST_F(WebContentsImplTest, FilterURLs) {
// Check that an IPC with about:whatever is correctly normalized.
other_contents->TestDidFailLoadWithError(
- 1, url_from_ipc, true, 1, string16());
+ 1, url_from_ipc, true, 1, base::string16());
EXPECT_EQ(url_normalized, other_observer.last_url());
}
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index fc27aceed0..f66b5ec14f 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -80,7 +80,7 @@ void WebContentsViewAndroid::GetContainerBounds(gfx::Rect* out) const {
*out = rwhv->GetViewBounds();
}
-void WebContentsViewAndroid::SetPageTitle(const string16& title) {
+void WebContentsViewAndroid::SetPageTitle(const base::string16& title) {
if (content_view_core_)
content_view_core_->SetTitle(title);
}
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h
index bcfc0cf472..849ca6dc8d 100644
--- a/content/browser/web_contents/web_contents_view_android.h
+++ b/content/browser/web_contents/web_contents_view_android.h
@@ -57,7 +57,7 @@ class WebContentsViewAndroid : public WebContentsViewPort,
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 353da78864..75ca4e6fca 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -249,7 +249,7 @@ void PrepareDragForFileContents(const DropData& drop_data,
// Images without ALT text will only have a file extension so we need to
// synthesize one from the provided extension and URL.
if (file_name.BaseName().RemoveExtension().empty()) {
- const string16 extension = file_name.Extension();
+ const base::string16 extension = file_name.Extension();
// Retrieve the name from the URL.
file_name = base::FilePath(net::GetSuggestedFilename(
drop_data.url, "", "", "", "", "")).ReplaceExtension(extension);
@@ -296,20 +296,20 @@ void PrepareDragData(const DropData& drop_data,
// Utility to fill a DropData object from ui::OSExchangeData.
void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
- string16 plain_text;
+ base::string16 plain_text;
data.GetString(&plain_text);
if (!plain_text.empty())
drop_data->text = base::NullableString16(plain_text, false);
GURL url;
- string16 url_title;
+ base::string16 url_title;
data.GetURLAndTitle(&url, &url_title);
if (url.is_valid()) {
drop_data->url = url;
drop_data->url_title = url_title;
}
- string16 html;
+ base::string16 html;
GURL html_base_url;
data.GetHtml(&html, &html_base_url);
if (!html.empty())
@@ -1298,7 +1298,7 @@ RenderWidgetHostView* WebContentsViewAura::CreateViewForPopupWidget(
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
-void WebContentsViewAura::SetPageTitle(const string16& title) {
+void WebContentsViewAura::SetPageTitle(const base::string16& title) {
window_->set_title(title);
}
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
index 7d377b0559..a0597d38fa 100644
--- a/content/browser/web_contents/web_contents_view_aura.h
+++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -118,7 +118,7 @@ class CONTENT_EXPORT WebContentsViewAura
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index 3214c13c11..687ce57606 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -196,14 +196,14 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
{
// Do a swipe-right now. That should navigate backwards.
- string16 expected_title = ASCIIToUTF16("Title: #1");
+ base::string16 expected_title = ASCIIToUTF16("Title: #1");
content::TitleWatcher title_watcher(web_contents, expected_title);
generator.GestureScrollSequence(
gfx::Point(bounds.x() + 2, bounds.y() + 10),
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(kScrollDurationMs),
kScrollSteps);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
@@ -214,14 +214,14 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
{
// Do a fling-right now. That should navigate backwards.
- string16 expected_title = ASCIIToUTF16("Title:");
+ base::string16 expected_title = ASCIIToUTF16("Title:");
content::TitleWatcher title_watcher(web_contents, expected_title);
generator.GestureScrollSequence(
gfx::Point(bounds.x() + 2, bounds.y() + 10),
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(kScrollDurationMs),
kScrollSteps);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
@@ -232,14 +232,14 @@ class WebContentsViewAuraTest : public ContentBrowserTest {
{
// Do a swipe-left now. That should navigate forward.
- string16 expected_title = ASCIIToUTF16("Title: #1");
+ base::string16 expected_title = ASCIIToUTF16("Title: #1");
content::TitleWatcher title_watcher(web_contents, expected_title);
generator.GestureScrollSequence(
gfx::Point(bounds.right() - 10, bounds.y() + 10),
gfx::Point(bounds.x() + 2, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(kScrollDurationMs),
kScrollSteps);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
@@ -438,7 +438,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, OverscrollScreenshot) {
{
// Now, swipe right to navigate backwards. This should navigate away from
// index 3 to index 2, and index 3 should have a screenshot.
- string16 expected_title = ASCIIToUTF16("Title: #2");
+ base::string16 expected_title = ASCIIToUTF16("Title: #2");
content::TitleWatcher title_watcher(web_contents, expected_title);
aura::Window* content = web_contents->GetView()->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
@@ -448,7 +448,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, OverscrollScreenshot) {
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(20),
1);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
EXPECT_EQ(2, GetCurrentIndex());
screenshot_manager()->WaitUntilScreenshotIsReady();
@@ -469,10 +469,10 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, OverscrollScreenshot) {
{
// Navigate back in history.
- string16 expected_title = ASCIIToUTF16("Title: #3");
+ base::string16 expected_title = ASCIIToUTF16("Title: #3");
content::TitleWatcher title_watcher(web_contents, expected_title);
web_contents->GetController().GoBack();
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
EXPECT_EQ(3, GetCurrentIndex());
screenshot_manager()->WaitUntilScreenshotIsReady();
@@ -641,7 +641,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
// Do a swipe left to start a forward navigation. Then quickly do a swipe
// right.
- string16 expected_title = ASCIIToUTF16("Title: #2");
+ base::string16 expected_title = ASCIIToUTF16("Title: #2");
content::TitleWatcher title_watcher(web_contents, expected_title);
NavigationWatcher nav_watcher(web_contents);
@@ -657,7 +657,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(2000),
10);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
EXPECT_EQ(2, GetCurrentIndex());
diff --git a/content/browser/web_contents/web_contents_view_gtk.cc b/content/browser/web_contents/web_contents_view_gtk.cc
index 4e3874fd1e..bf4dcb7fd3 100644
--- a/content/browser/web_contents/web_contents_view_gtk.cc
+++ b/content/browser/web_contents/web_contents_view_gtk.cc
@@ -246,7 +246,7 @@ RenderWidgetHostView* WebContentsViewGtk::CreateViewForPopupWidget(
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
-void WebContentsViewGtk::SetPageTitle(const string16& title) {
+void WebContentsViewGtk::SetPageTitle(const base::string16& title) {
// Set the window name to include the page title so it's easier to spot
// when debugging (e.g. via xwininfo -tree).
gfx::NativeView content_view = GetContentNativeView();
diff --git a/content/browser/web_contents/web_contents_view_gtk.h b/content/browser/web_contents/web_contents_view_gtk.h
index 41f84ab7af..7a8d25e450 100644
--- a/content/browser/web_contents/web_contents_view_gtk.h
+++ b/content/browser/web_contents/web_contents_view_gtk.h
@@ -66,7 +66,7 @@ class CONTENT_EXPORT WebContentsViewGtk
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc
index ac236da041..cbfb7903da 100644
--- a/content/browser/web_contents/web_contents_view_guest.cc
+++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -106,6 +106,15 @@ void WebContentsViewGuest::SetAllowOverlappingViews(bool overlapping) {
bool WebContentsViewGuest::GetAllowOverlappingViews() const {
return platform_view_->GetAllowOverlappingViews();
}
+
+void WebContentsViewGuest::SetOverlayView(
+ WebContentsView* overlay, const gfx::Point& offset) {
+ platform_view_->SetOverlayView(overlay, offset);
+}
+
+void WebContentsViewGuest::RemoveOverlayView() {
+ platform_view_->RemoveOverlayView();
+}
#endif
void WebContentsViewGuest::CreateView(const gfx::Size& initial_size,
@@ -142,7 +151,7 @@ RenderWidgetHostView* WebContentsViewGuest::CreateViewForPopupWidget(
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
-void WebContentsViewGuest::SetPageTitle(const string16& title) {
+void WebContentsViewGuest::SetPageTitle(const base::string16& title) {
}
void WebContentsViewGuest::RenderViewCreated(RenderViewHost* host) {
diff --git a/content/browser/web_contents/web_contents_view_guest.h b/content/browser/web_contents/web_contents_view_guest.h
index 1e1d812e37..68fb473d70 100644
--- a/content/browser/web_contents/web_contents_view_guest.h
+++ b/content/browser/web_contents/web_contents_view_guest.h
@@ -56,6 +56,9 @@ class CONTENT_EXPORT WebContentsViewGuest
#if defined(OS_MACOSX)
virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
virtual bool GetAllowOverlappingViews() const OVERRIDE;
+ virtual void SetOverlayView(WebContentsView* overlay,
+ const gfx::Point& offset) OVERRIDE;
+ virtual void RemoveOverlayView() OVERRIDE;
#endif
// WebContentsViewPort implementation ----------------------------------------
@@ -65,7 +68,7 @@ class CONTENT_EXPORT WebContentsViewGuest
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h
index 3d0b94f92e..0dadbad9eb 100644
--- a/content/browser/web_contents/web_contents_view_mac.h
+++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -80,6 +80,9 @@ class WebContentsViewMac : public WebContentsViewPort,
virtual gfx::Rect GetViewBounds() const OVERRIDE;
virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
virtual bool GetAllowOverlappingViews() const OVERRIDE;
+ virtual void SetOverlayView(WebContentsView* overlay,
+ const gfx::Point& offset) OVERRIDE;
+ virtual void RemoveOverlayView() OVERRIDE;
// WebContentsViewPort implementation ----------------------------------------
virtual void CreateView(
@@ -88,7 +91,7 @@ class WebContentsViewMac : public WebContentsViewPort,
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
@@ -121,6 +124,9 @@ class WebContentsViewMac : public WebContentsViewPort,
WebContentsViewDelegate* delegate() { return delegate_.get(); }
private:
+ // Updates overlay view on current RenderWidgetHostView.
+ void UpdateRenderWidgetHostViewOverlay();
+
// The WebContentsImpl whose contents we display.
WebContentsImpl* web_contents_;
@@ -137,6 +143,17 @@ class WebContentsViewMac : public WebContentsViewPort,
// Whether to allow overlapping views.
bool allow_overlapping_views_;
+ // The overlay view which is rendered above this one.
+ // Overlay view has |underlay_view_| set to this view.
+ WebContentsViewMac* overlay_view_;
+
+ // The offset of overlay view relative to this view.
+ gfx::Point overlay_view_offset_;
+
+ // The underlay view which this view is rendered above.
+ // Underlay view has |overlay_view_| set to this view.
+ WebContentsViewMac* underlay_view_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewMac);
};
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 4283ca958d..527ebc024d 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -81,7 +81,9 @@ WebContentsViewMac::WebContentsViewMac(WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
: web_contents_(web_contents),
delegate_(delegate),
- allow_overlapping_views_(false) {
+ allow_overlapping_views_(false),
+ overlay_view_(NULL),
+ underlay_view_(NULL) {
}
WebContentsViewMac::~WebContentsViewMac() {
@@ -277,6 +279,54 @@ bool WebContentsViewMac::GetAllowOverlappingViews() const {
return allow_overlapping_views_;
}
+void WebContentsViewMac::SetOverlayView(
+ WebContentsView* overlay, const gfx::Point& offset) {
+ DCHECK(!underlay_view_);
+ if (overlay_view_)
+ RemoveOverlayView();
+
+ overlay_view_ = static_cast<WebContentsViewMac*>(overlay);
+ DCHECK(!overlay_view_->overlay_view_);
+ overlay_view_->underlay_view_ = this;
+ overlay_view_offset_ = offset;
+ UpdateRenderWidgetHostViewOverlay();
+}
+
+void WebContentsViewMac::RemoveOverlayView() {
+ DCHECK(overlay_view_);
+
+ RenderWidgetHostViewMac* rwhv = static_cast<RenderWidgetHostViewMac*>(
+ web_contents_->GetRenderWidgetHostView());
+ if (rwhv)
+ rwhv->RemoveOverlayView();
+
+ overlay_view_->underlay_view_ = NULL;
+ overlay_view_ = NULL;
+}
+
+void WebContentsViewMac::UpdateRenderWidgetHostViewOverlay() {
+ RenderWidgetHostViewMac* rwhv = static_cast<RenderWidgetHostViewMac*>(
+ web_contents_->GetRenderWidgetHostView());
+ if (!rwhv)
+ return;
+
+ if (overlay_view_) {
+ RenderWidgetHostViewMac* overlay_rwhv =
+ static_cast<RenderWidgetHostViewMac*>(
+ overlay_view_->web_contents_->GetRenderWidgetHostView());
+ if (overlay_rwhv)
+ rwhv->SetOverlayView(overlay_rwhv, overlay_view_offset_);
+ }
+
+ if (underlay_view_) {
+ RenderWidgetHostViewMac* underlay_rwhv =
+ static_cast<RenderWidgetHostViewMac*>(
+ underlay_view_->web_contents_->GetRenderWidgetHostView());
+ if (underlay_rwhv)
+ underlay_rwhv->SetOverlayView(rwhv, underlay_view_->overlay_view_offset_);
+ }
+}
+
void WebContentsViewMac::CreateView(
const gfx::Size& initial_size, gfx::NativeView context) {
WebContentsViewCocoa* view =
@@ -332,7 +382,7 @@ RenderWidgetHostView* WebContentsViewMac::CreateViewForPopupWidget(
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
-void WebContentsViewMac::SetPageTitle(const string16& title) {
+void WebContentsViewMac::SetPageTitle(const base::string16& title) {
// Meaningless on the Mac; widgets don't have a "title" attribute
}
@@ -345,6 +395,7 @@ void WebContentsViewMac::RenderViewCreated(RenderViewHost* host) {
}
void WebContentsViewMac::RenderViewSwappedIn(RenderViewHost* host) {
+ UpdateRenderWidgetHostViewOverlay();
}
void WebContentsViewMac::SetOverscrollControllerEnabled(bool enabled) {
diff --git a/content/browser/web_contents/web_contents_view_win.cc b/content/browser/web_contents/web_contents_view_win.cc
index 92548d2dca..8360d8c5f5 100644
--- a/content/browser/web_contents/web_contents_view_win.cc
+++ b/content/browser/web_contents/web_contents_view_win.cc
@@ -228,7 +228,7 @@ RenderWidgetHostView* WebContentsViewWin::CreateViewForPopupWidget(
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
-void WebContentsViewWin::SetPageTitle(const string16& title) {
+void WebContentsViewWin::SetPageTitle(const base::string16& title) {
// It's possible to get this after the hwnd has been destroyed.
if (GetNativeView())
::SetWindowText(GetNativeView(), title.c_str());
diff --git a/content/browser/web_contents/web_contents_view_win.h b/content/browser/web_contents/web_contents_view_win.h
index 505addddec..9b052e20a2 100644
--- a/content/browser/web_contents/web_contents_view_win.h
+++ b/content/browser/web_contents/web_contents_view_win.h
@@ -73,7 +73,7 @@ class CONTENT_EXPORT WebContentsViewWin
RenderWidgetHost* render_widget_host) OVERRIDE;
virtual RenderWidgetHostView* CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) OVERRIDE;
- virtual void SetPageTitle(const string16& title) OVERRIDE;
+ virtual void SetPageTitle(const base::string16& title) OVERRIDE;
virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
diff --git a/content/browser/web_contents/web_drag_dest_gtk.cc b/content/browser/web_contents/web_drag_dest_gtk.cc
index bb9a4d42a7..738d6b59a8 100644
--- a/content/browser/web_contents/web_drag_dest_gtk.cc
+++ b/content/browser/web_contents/web_drag_dest_gtk.cc
@@ -204,7 +204,8 @@ void WebDragDestGtk::OnDragDataReceived(
if (url.SchemeIs(chrome::kFileScheme) &&
net::FileURLToFilePath(url, &file_path)) {
drop_data_->filenames.push_back(
- DropData::FileInfo(UTF8ToUTF16(file_path.value()), string16()));
+ DropData::FileInfo(UTF8ToUTF16(file_path.value()),
+ base::string16()));
// This is a hack. Some file managers also populate text/plain with
// a file URL when dragging files, so we clear it to avoid exposing
// it to the web content.
diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm
index b3fefcad00..8768bed657 100644
--- a/content/browser/web_contents/web_drag_dest_mac.mm
+++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -290,7 +290,7 @@ int GetModifierFlags() {
if (exists) {
data->filenames.push_back(
DropData::FileInfo(
- base::SysNSStringToUTF16(filename), string16()));
+ base::SysNSStringToUTF16(filename), base::string16()));
}
}
}
diff --git a/content/browser/web_contents/web_drag_dest_mac_unittest.mm b/content/browser/web_contents/web_drag_dest_mac_unittest.mm
index 48719de7b7..a7dcedecb0 100644
--- a/content/browser/web_contents/web_drag_dest_mac_unittest.mm
+++ b/content/browser/web_contents/web_drag_dest_mac_unittest.mm
@@ -6,9 +6,9 @@
#import "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "content/browser/renderer_host/test_render_view_host.h"
#import "content/browser/web_contents/web_drag_dest_mac.h"
#include "content/public/common/drop_data.h"
+#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "third_party/mozilla/NSPasteboard+Utils.h"
@@ -85,7 +85,7 @@ TEST_F(WebDragDestTest, URL) {
NSString* url = nil;
NSString* title = nil;
GURL result_url;
- string16 result_title;
+ base::string16 result_title;
// Put a URL on the pasteboard and check it.
pboard = [NSPasteboard pasteboardWithUniqueName];
diff --git a/content/browser/web_contents/web_drag_source_gtk.h b/content/browser/web_contents/web_drag_source_gtk.h
index 577f60b086..8a7c7b28a9 100644
--- a/content/browser/web_contents/web_drag_source_gtk.h
+++ b/content/browser/web_contents/web_drag_source_gtk.h
@@ -92,7 +92,7 @@ class CONTENT_EXPORT WebDragSourceGtk :
GdkDragContext* drag_context_;
// The file mime type for a drag-out download.
- string16 wide_download_mime_type_;
+ base::string16 wide_download_mime_type_;
// The file name to be saved to for a drag-out download.
base::FilePath download_file_name_;
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm
index 805e73bdd4..c66732050c 100644
--- a/content/browser/web_contents/web_drag_source_mac.mm
+++ b/content/browser/web_contents/web_drag_source_mac.mm
@@ -49,10 +49,10 @@ namespace {
// |NSURLPboardType|.
NSString* const kNSURLTitlePboardType = @"public.url-name";
-// Converts a string16 into a FilePath. Use this method instead of
+// Converts a base::string16 into a FilePath. Use this method instead of
// -[NSString fileSystemRepresentation] to prevent exceptions from being thrown.
// See http://crbug.com/78782 for more info.
-base::FilePath FilePathFromFilename(const string16& filename) {
+base::FilePath FilePathFromFilename(const base::string16& filename) {
NSString* str = SysUTF16ToNSString(filename);
char buf[MAXPATHLEN];
if (![str getFileSystemRepresentation:buf maxLength:sizeof(buf)])
@@ -71,7 +71,7 @@ base::FilePath GetFileNameFromDragData(const DropData& drop_data) {
// synthesize one from the provided extension and URL.
if (file_name.empty()) {
// Retrieve the name from the URL.
- string16 suggested_filename =
+ base::string16 suggested_filename =
net::GetSuggestedFilename(drop_data.url, "", "", "", "", "");
const std::string extension = file_name.Extension();
file_name = FilePathFromFilename(suggested_filename);
@@ -147,7 +147,7 @@ void PromiseWriterHelper(const DropData& drop_data,
- (void)lazyWriteToPasteboard:(NSPasteboard*)pboard forType:(NSString*)type {
// NSHTMLPboardType requires the character set to be declared. Otherwise, it
// assumes US-ASCII. Awesome.
- const string16 kHtmlHeader = ASCIIToUTF16(
+ const base::string16 kHtmlHeader = ASCIIToUTF16(
"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">");
// Be extra paranoid; avoid crashing.
@@ -386,7 +386,7 @@ void PromiseWriterHelper(const DropData& drop_data,
downloadFileName_ = GetFileNameFromDragData(*dropData_);
net::GetMimeTypeFromExtension(downloadFileName_.Extension(), &mimeType);
} else {
- string16 mimeType16;
+ base::string16 mimeType16;
base::FilePath fileName;
if (content::ParseDownloadMetadata(
dropData_->download_metadata,
diff --git a/content/browser/webui/web_ui_data_source_impl.cc b/content/browser/webui/web_ui_data_source_impl.cc
index 6a5b602562..6775eb739d 100644
--- a/content/browser/webui/web_ui_data_source_impl.cc
+++ b/content/browser/webui/web_ui_data_source_impl.cc
@@ -95,7 +95,7 @@ WebUIDataSourceImpl::~WebUIDataSourceImpl() {
}
void WebUIDataSourceImpl::AddString(const std::string& name,
- const string16& value) {
+ const base::string16& value) {
localized_strings_.SetString(name, value);
}
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h
index 1f8100469e..91ec087cfc 100644
--- a/content/browser/webui/web_ui_data_source_impl.h
+++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -28,7 +28,7 @@ class CONTENT_EXPORT WebUIDataSourceImpl
public:
// WebUIDataSource implementation:
virtual void AddString(const std::string& name,
- const string16& value) OVERRIDE;
+ const base::string16& value) OVERRIDE;
virtual void AddString(const std::string& name,
const std::string& value) OVERRIDE;
virtual void AddLocalizedString(const std::string& name, int ids) OVERRIDE;
diff --git a/content/browser/webui/web_ui_data_source_unittest.cc b/content/browser/webui/web_ui_data_source_unittest.cc
index f384a43e94..a5da7eb821 100644
--- a/content/browser/webui/web_ui_data_source_unittest.cc
+++ b/content/browser/webui/web_ui_data_source_unittest.cc
@@ -25,10 +25,10 @@ class TestClient : public TestContentClient {
TestClient() {}
virtual ~TestClient() {}
- virtual string16 GetLocalizedString(int message_id) const OVERRIDE {
+ virtual base::string16 GetLocalizedString(int message_id) const OVERRIDE {
if (message_id == kDummyStringId)
return UTF8ToUTF16(kDummyString);
- return string16();
+ return base::string16();
}
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc
index e54a6d8c27..4774e4f17a 100644
--- a/content/browser/webui/web_ui_impl.cc
+++ b/content/browser/webui/web_ui_impl.cc
@@ -27,10 +27,10 @@ namespace content {
const WebUI::TypeID WebUI::kNoWebUI = NULL;
// static
-string16 WebUI::GetJavascriptCall(
+base::string16 WebUI::GetJavascriptCall(
const std::string& function_name,
const std::vector<const Value*>& arg_list) {
- string16 parameters;
+ base::string16 parameters;
std::string json;
for (size_t i = 0; i < arg_list.size(); ++i) {
if (i > 0)
@@ -106,11 +106,11 @@ ui::ScaleFactor WebUIImpl::GetDeviceScaleFactor() const {
return GetScaleFactorForView(web_contents_->GetRenderWidgetHostView());
}
-const string16& WebUIImpl::GetOverriddenTitle() const {
+const base::string16& WebUIImpl::GetOverriddenTitle() const {
return overridden_title_;
}
-void WebUIImpl::OverrideTitle(const string16& title) {
+void WebUIImpl::OverrideTitle(const base::string16& title) {
overridden_title_ = title;
}
@@ -144,7 +144,7 @@ void WebUIImpl::SetController(WebUIController* controller) {
void WebUIImpl::CallJavascriptFunction(const std::string& function_name) {
DCHECK(IsStringASCII(function_name));
- string16 javascript = ASCIIToUTF16(function_name + "();");
+ base::string16 javascript = ASCIIToUTF16(function_name + "();");
ExecuteJavascript(javascript);
}
@@ -230,7 +230,7 @@ void WebUIImpl::AddMessageHandler(WebUIMessageHandler* handler) {
handlers_.push_back(handler);
}
-void WebUIImpl::ExecuteJavascript(const string16& javascript) {
+void WebUIImpl::ExecuteJavascript(const base::string16& javascript) {
static_cast<RenderViewHostImpl*>(
web_contents_->GetRenderViewHost())->ExecuteJavascriptInWebFrame(
ASCIIToUTF16(frame_xpath_), javascript);
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h
index a359117ced..8715e43e22 100644
--- a/content/browser/webui/web_ui_impl.h
+++ b/content/browser/webui/web_ui_impl.h
@@ -33,8 +33,8 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
virtual WebUIController* GetController() const OVERRIDE;
virtual void SetController(WebUIController* controller) OVERRIDE;
virtual ui::ScaleFactor GetDeviceScaleFactor() const OVERRIDE;
- virtual const string16& GetOverriddenTitle() const OVERRIDE;
- virtual void OverrideTitle(const string16& title) OVERRIDE;
+ virtual const base::string16& GetOverriddenTitle() const OVERRIDE;
+ virtual void OverrideTitle(const base::string16& title) OVERRIDE;
virtual PageTransition GetLinkTransitionType() const OVERRIDE;
virtual void SetLinkTransitionType(PageTransition type) OVERRIDE;
virtual int GetBindings() const OVERRIDE;
@@ -78,7 +78,7 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
const base::ListValue& args);
// Execute a string of raw Javascript on the page.
- void ExecuteJavascript(const string16& javascript);
+ void ExecuteJavascript(const base::string16& javascript);
// A map of message name -> message handling callback.
typedef std::map<std::string, MessageCallback> MessageCallbackMap;
@@ -86,7 +86,7 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
// Options that may be overridden by individual Web UI implementations. The
// bool options default to false. See the public getters for more information.
- string16 overridden_title_; // Defaults to empty string.
+ base::string16 overridden_title_; // Defaults to empty string.
PageTransition link_transition_type_; // Defaults to LINK.
int bindings_; // The bindings from BindingsPolicy that should be enabled for
// this page.
diff --git a/content/browser/webui/web_ui_message_handler.cc b/content/browser/webui/web_ui_message_handler.cc
index db554c0ed8..57b2c46b86 100644
--- a/content/browser/webui/web_ui_message_handler.cc
+++ b/content/browser/webui/web_ui_message_handler.cc
@@ -36,12 +36,12 @@ bool WebUIMessageHandler::ExtractDoubleValue(const ListValue* value,
return false;
}
-string16 WebUIMessageHandler::ExtractStringValue(const ListValue* value) {
- string16 string16_value;
+base::string16 WebUIMessageHandler::ExtractStringValue(const ListValue* value) {
+ base::string16 string16_value;
if (value->GetString(0, &string16_value))
return string16_value;
NOTREACHED();
- return string16();
+ return base::string16();
}
} // namespace content
diff --git a/content/browser/webui/web_ui_message_handler_unittest.cc b/content/browser/webui/web_ui_message_handler_unittest.cc
index e38acd7e31..33cdb61fb1 100644
--- a/content/browser/webui/web_ui_message_handler_unittest.cc
+++ b/content/browser/webui/web_ui_message_handler_unittest.cc
@@ -14,9 +14,9 @@ namespace content {
TEST(WebUIMessageHandlerTest, ExtractIntegerValue) {
ListValue list;
int value, zero_value = 0, neg_value = -1234, pos_value = 1234;
- string16 zero_string(UTF8ToUTF16("0"));
- string16 neg_string(UTF8ToUTF16("-1234"));
- string16 pos_string(UTF8ToUTF16("1234"));
+ base::string16 zero_string(UTF8ToUTF16("0"));
+ base::string16 neg_string(UTF8ToUTF16("-1234"));
+ base::string16 pos_string(UTF8ToUTF16("1234"));
list.Append(new base::FundamentalValue(zero_value));
EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
@@ -51,9 +51,9 @@ TEST(WebUIMessageHandlerTest, ExtractIntegerValue) {
TEST(WebUIMessageHandlerTest, ExtractDoubleValue) {
base::ListValue list;
double value, zero_value = 0.0, neg_value = -1234.5, pos_value = 1234.5;
- string16 zero_string(UTF8ToUTF16("0"));
- string16 neg_string(UTF8ToUTF16("-1234.5"));
- string16 pos_string(UTF8ToUTF16("1234.5"));
+ base::string16 zero_string(UTF8ToUTF16("0"));
+ base::string16 neg_string(UTF8ToUTF16("-1234.5"));
+ base::string16 pos_string(UTF8ToUTF16("1234.5"));
list.Append(new base::FundamentalValue(zero_value));
EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
@@ -87,10 +87,10 @@ TEST(WebUIMessageHandlerTest, ExtractDoubleValue) {
TEST(WebUIMessageHandlerTest, ExtractStringValue) {
base::ListValue list;
- string16 in_string(UTF8ToUTF16(
+ base::string16 in_string(UTF8ToUTF16(
"The facts, though interesting, are irrelevant."));
list.Append(new base::StringValue(in_string));
- string16 out_string = WebUIMessageHandler::ExtractStringValue(&list);
+ base::string16 out_string = WebUIMessageHandler::ExtractStringValue(&list);
EXPECT_EQ(in_string, out_string);
}
diff --git a/content/browser/worker_host/test/worker_browsertest.cc b/content/browser/worker_host/test/worker_browsertest.cc
index a71a28e1f9..acd00fba10 100644
--- a/content/browser/worker_host/test/worker_browsertest.cc
+++ b/content/browser/worker_host/test/worker_browsertest.cc
@@ -42,10 +42,10 @@ class WorkerTest : public ContentBrowserTest {
const std::string& test_case,
const std::string& query) {
GURL url = GetTestURL(test_case, query);
- const string16 expected_title = ASCIIToUTF16("OK");
+ const base::string16 expected_title = ASCIIToUTF16("OK");
TitleWatcher title_watcher(window->web_contents(), expected_title);
NavigateToURL(window, url);
- string16 final_title = title_watcher.WaitAndGetTitle();
+ base::string16 final_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, final_title);
}
@@ -275,10 +275,10 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WebSocketSharedWorker) {
// Run test.
Shell* window = shell();
- const string16 expected_title = ASCIIToUTF16("OK");
+ const base::string16 expected_title = ASCIIToUTF16("OK");
TitleWatcher title_watcher(window->web_contents(), expected_title);
NavigateToURL(window, url);
- string16 final_title = title_watcher.WaitAndGetTitle();
+ base::string16 final_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, final_title);
}
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc
index 08277da2a4..fae589bf47 100644
--- a/content/browser/worker_host/worker_process_host.cc
+++ b/content/browser/worker_host/worker_process_host.cc
@@ -372,8 +372,8 @@ void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) {
void WorkerProcessHost::OnAllowDatabase(int worker_route_id,
const GURL& url,
- const string16& name,
- const string16& display_name,
+ const base::string16& name,
+ const base::string16& display_name,
unsigned long estimated_size,
bool* result) {
*result = GetContentClient()->browser()->AllowWorkerDatabase(
@@ -390,7 +390,7 @@ void WorkerProcessHost::OnAllowFileSystem(int worker_route_id,
void WorkerProcessHost::OnAllowIndexedDB(int worker_route_id,
const GURL& url,
- const string16& name,
+ const base::string16& name,
bool* result) {
*result = GetContentClient()->browser()->AllowWorkerIndexedDB(
url, name, resource_context_, GetRenderViewIDsForWorker(worker_route_id));
@@ -572,7 +572,7 @@ net::URLRequestContext* WorkerProcessHost::GetRequestContext(
WorkerProcessHost::WorkerInstance::WorkerInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
int worker_route_id,
int parent_process_id,
int64 main_resource_appcache_id,
@@ -593,7 +593,7 @@ WorkerProcessHost::WorkerInstance::WorkerInstance(
WorkerProcessHost::WorkerInstance::WorkerInstance(
const GURL& url,
bool shared,
- const string16& name,
+ const base::string16& name,
ResourceContext* resource_context,
const WorkerStoragePartition& partition)
: url_(url),
@@ -618,7 +618,7 @@ WorkerProcessHost::WorkerInstance::~WorkerInstance() {
// b) the names are both empty, and the urls are equal
bool WorkerProcessHost::WorkerInstance::Matches(
const GURL& match_url,
- const string16& match_name,
+ const base::string16& match_name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) const {
// Only match open shared workers.
diff --git a/content/browser/worker_host/worker_process_host.h b/content/browser/worker_host/worker_process_host.h
index 0a9ea6005b..c3fa64d6d7 100644
--- a/content/browser/worker_host/worker_process_host.h
+++ b/content/browser/worker_host/worker_process_host.h
@@ -57,7 +57,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
class WorkerInstance {
public:
WorkerInstance(const GURL& url,
- const string16& name,
+ const base::string16& name,
int worker_route_id,
int parent_process_id,
int64 main_resource_appcache_id,
@@ -66,7 +66,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
// Used for pending instances. Rest of the parameters are ignored.
WorkerInstance(const GURL& url,
bool shared,
- const string16& name,
+ const base::string16& name,
ResourceContext* resource_context,
const WorkerStoragePartition& partition);
~WorkerInstance();
@@ -92,7 +92,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
// applies to shared workers.
bool Matches(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) const;
@@ -107,7 +107,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
bool closed() const { return closed_; }
void set_closed(bool closed) { closed_ = closed; }
const GURL& url() const { return url_; }
- const string16 name() const { return name_; }
+ const base::string16 name() const { return name_; }
int worker_route_id() const { return worker_route_id_; }
int parent_process_id() const { return parent_process_id_; }
int64 main_resource_appcache_id() const {
@@ -127,7 +127,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
// Set of all filters (clients) associated with this worker.
GURL url_;
bool closed_;
- string16 name_;
+ base::string16 name_;
int worker_route_id_;
int parent_process_id_;
int64 main_resource_appcache_id_;
@@ -196,8 +196,8 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
void OnWorkerContextClosed(int worker_route_id);
void OnAllowDatabase(int worker_route_id,
const GURL& url,
- const string16& name,
- const string16& display_name,
+ const base::string16& name,
+ const base::string16& display_name,
unsigned long estimated_size,
bool* result);
void OnAllowFileSystem(int worker_route_id,
@@ -205,7 +205,7 @@ class WorkerProcessHost : public BrowserChildProcessHostDelegate,
bool* result);
void OnAllowIndexedDB(int worker_route_id,
const GURL& url,
- const string16& name,
+ const base::string16& name,
bool* result);
void OnForceKillWorkerProcess();
diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc
index d2ab272922..3ebab469ff 100644
--- a/content/browser/worker_host/worker_service_impl.cc
+++ b/content/browser/worker_host/worker_service_impl.cc
@@ -650,7 +650,7 @@ void WorkerServiceImpl::NotifyWorkerProcessCreated() {
WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) {
for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
@@ -667,7 +667,7 @@ WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindPendingInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) {
// Walk the pending instances looking for a matching pending worker.
@@ -684,7 +684,7 @@ WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindPendingInstance(
void WorkerServiceImpl::RemovePendingInstances(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& partition,
ResourceContext* resource_context) {
// Walk the pending instances looking for a matching pending worker.
@@ -701,7 +701,7 @@ void WorkerServiceImpl::RemovePendingInstances(
WorkerProcessHost::WorkerInstance* WorkerServiceImpl::CreatePendingInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
ResourceContext* resource_context,
const WorkerStoragePartition& partition) {
// Look for an existing pending shared worker.
diff --git a/content/browser/worker_host/worker_service_impl.h b/content/browser/worker_host/worker_service_impl.h
index 9da0d19cd2..4d5127aec2 100644
--- a/content/browser/worker_host/worker_service_impl.h
+++ b/content/browser/worker_host/worker_service_impl.h
@@ -108,23 +108,23 @@ class CONTENT_EXPORT WorkerServiceImpl
// APIs for manipulating our set of pending shared worker instances.
WorkerProcessHost::WorkerInstance* CreatePendingInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
ResourceContext* resource_context,
const WorkerStoragePartition& worker_partition);
WorkerProcessHost::WorkerInstance* FindPendingInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& worker_partition,
ResourceContext* resource_context);
void RemovePendingInstances(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& worker_partition,
ResourceContext* resource_context);
WorkerProcessHost::WorkerInstance* FindSharedWorkerInstance(
const GURL& url,
- const string16& name,
+ const base::string16& name,
const WorkerStoragePartition& worker_partition,
ResourceContext* resource_context);